diff options
author | Sam Davis | 2012-01-09 18:05:59 +0000 |
---|---|---|
committer | Steffen Pingel | 2012-01-11 12:33:53 +0000 |
commit | 336f105831d7b57aca93db036ad906ea45e38216 (patch) | |
tree | 3e1765d3daf4f976baef732530ddc8144e301c1f | |
parent | 53dd145cc529445f0ba9e3ef3a59d241d840469e (diff) | |
download | org.eclipse.mylyn.tasks-336f105831d7b57aca93db036ad906ea45e38216.tar.gz org.eclipse.mylyn.tasks-336f105831d7b57aca93db036ad906ea45e38216.tar.xz org.eclipse.mylyn.tasks-336f105831d7b57aca93db036ad906ea45e38216.zip |
NEW - bug 364999: [patch] User can select repository when clicking a
task hyperlinks in the task editor
https://bugs.eclipse.org/bugs/show_bug.cgi?id=364999
Change-Id: I08ace7988d16a40d2b4bb57fdb5b3509b635a78b
5 files changed, 238 insertions, 22 deletions
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 a55247efb..5586fe667 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 @@ -20,6 +20,7 @@ import org.eclipse.mylyn.tasks.tests.core.TaskListUnmatchedContainerTest; import org.eclipse.mylyn.tasks.tests.core.TaskRepositoryLocationTest; import org.eclipse.mylyn.tasks.tests.data.TaskDataExternalizerTest; import org.eclipse.mylyn.tasks.tests.data.Xml11InputStreamTest; +import org.eclipse.mylyn.tasks.tests.ui.MultipleTaskHyperlinkDetectorTest; import org.eclipse.mylyn.tasks.tests.ui.RetrieveTitleFromUrlTest; import org.eclipse.mylyn.tasks.tests.ui.TaskAttachmentPropertyTesterTest; import org.eclipse.mylyn.tasks.tests.ui.TaskHyperlinkDetectorTest; @@ -113,7 +114,7 @@ public class AllTasksTests { // XXX long running tests, put back? //suite.addTestSuite(QueryExportImportTest.class); //suite.addTestSuite(BackgroundSaveTest.class); - + suite.addTestSuite(MultipleTaskHyperlinkDetectorTest.class); return suite; } diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/MultipleTaskHyperlinkDetectorTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/MultipleTaskHyperlinkDetectorTest.java new file mode 100644 index 000000000..161a3b745 --- /dev/null +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/MultipleTaskHyperlinkDetectorTest.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2012 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 java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import junit.framework.TestCase; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.mylyn.internal.tasks.ui.editors.MultipleTaskHyperlinkDetector; +import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkDetector; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryConnector; +import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryConnectorUi; +import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; +import org.eclipse.mylyn.tasks.ui.AbstractTaskHyperlinkDetector; +import org.eclipse.mylyn.tasks.ui.TaskHyperlink; +import org.eclipse.mylyn.tasks.ui.TasksUi; + +/** + * @author Sam Davis + * @author Steffen Pingel + */ +public class MultipleTaskHyperlinkDetectorTest extends TestCase { + + protected MockRepositoryConnectorUi connectorUi1; + + protected MockRepositoryConnectorUi connectorUi2; + + protected TaskRepository repository1a; + + protected TaskRepository repository1b; + + protected TaskRepository repository2; + + @Override + protected void setUp() throws Exception { + // define 2 repositories using "test xxx" as task id + repository1a = new TaskRepository(MockRepositoryConnector.CONNECTOR_KIND, + MockRepositoryConnector.REPOSITORY_URL + "1a"); + repository1b = new TaskRepository(MockRepositoryConnector.CONNECTOR_KIND, + MockRepositoryConnector.REPOSITORY_URL + "1b"); + connectorUi1 = new MockRepositoryConnectorUi() { + private final Pattern HYPERLINK_PATTERN = Pattern.compile("(test \\d+)"); + + @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]); + }; + }; + // define 1 repository using "xxx" as task id + repository2 = new TaskRepository(MockRepositoryConnector.CONNECTOR_KIND, MockRepositoryConnector.REPOSITORY_URL + + "2"); + connectorUi2 = new MockRepositoryConnectorUi(); + TasksUi.getRepositoryManager().addRepository(repository1a); + TasksUi.getRepositoryManager().addRepository(repository1b); + TasksUi.getRepositoryManager().addRepository(repository2); + } + + protected IHyperlink[] detect(final String text, int start, int length, TaskRepository textViewerRepository) { + AbstractTaskHyperlinkDetector detector = createHyperlinkDetector(textViewerRepository); + return detector.detectHyperlinks(new MockTextViewer(text), new Region(start, length), true); + } + + protected AbstractTaskHyperlinkDetector createHyperlinkDetector(final TaskRepository textViewerRepository) { + TaskHyperlinkDetector detector = new MultipleTaskHyperlinkDetector() { + @Override + protected AbstractRepositoryConnectorUi getConnectorUi(TaskRepository repository) { + if (repository.equals(repository1a) || repository.equals(repository1b)) { + return connectorUi1; + } else if (repository.equals(repository2)) { + return connectorUi2; + } + return super.getConnectorUi(repository); + } + + @Override + protected TaskRepository getTaskRepository(ITextViewer textViewer) { + return textViewerRepository; + } + }; + return detector; + } + + public void testSingleRepositoryMatches() { + IHyperlink[] links = detect("test 123 test 456 test 789", 9, 15, repository2); + assertNotNull(links); + assertEquals(2, links.length); + assertEquals(new Region(14, 3), links[0].getHyperlinkRegion()); + assertEquals(new Region(23, 1), links[1].getHyperlinkRegion()); + assertEquals(repository2, ((TaskHyperlink) links[0]).getRepository()); + } + + public void testMultipleRepositoriesMatch() { + IHyperlink[] links = detect("test 123 test 456 test 789", 9, 15, repository1a); + assertNotNull(links); + assertEquals(4, links.length); + assertEquals(new Region(9, 8), links[0].getHyperlinkRegion()); + assertEquals(new Region(9, 8), links[2].getHyperlinkRegion()); + assertEquals(Arrays.asList(repository1a, repository1b), + Arrays.asList(((TaskHyperlink) links[0]).getRepository(), ((TaskHyperlink) links[2]).getRepository())); + assertEquals(new Region(18, 6), links[1].getHyperlinkRegion()); + assertEquals(new Region(18, 6), links[3].getHyperlinkRegion()); + assertEquals(Arrays.asList(repository1a, repository1b), + Arrays.asList(((TaskHyperlink) links[1]).getRepository(), ((TaskHyperlink) links[3]).getRepository())); + } + +} diff --git a/org.eclipse.mylyn.tasks.ui/plugin.xml b/org.eclipse.mylyn.tasks.ui/plugin.xml index 0e69c4667..0b0dfdae6 100644 --- a/org.eclipse.mylyn.tasks.ui/plugin.xml +++ b/org.eclipse.mylyn.tasks.ui/plugin.xml @@ -1078,6 +1078,13 @@ name="%TaskHyperlinkDetector.name" targetId="org.eclipse.ui.DefaultTextEditor"> </hyperlinkDetector> + <hyperlinkDetector + class="org.eclipse.mylyn.internal.tasks.ui.editors.MultipleTaskHyperlinkDetector" + id="org.eclipse.mylyn.tasks.ui.hyperlinks.detectors.task.multiple" + name="%TaskHyperlinkDetector.name" + modifierKeys="Ctrl" + targetId="org.eclipse.mylyn.tasks.ui.TaskEditor"> + </hyperlinkDetector> <hyperlinkDetector class="org.eclipse.mylyn.internal.tasks.ui.editors.TaskUrlHyperlinkDetector" description="%TaskUrlHyperlinkDetector.description" diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/MultipleTaskHyperlinkDetector.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/MultipleTaskHyperlinkDetector.java new file mode 100644 index 000000000..39011475c --- /dev/null +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/MultipleTaskHyperlinkDetector.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2012 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.internal.tasks.ui.editors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.ui.TasksUi; + +/** + * @author Sam Davis + */ +public class MultipleTaskHyperlinkDetector extends TaskHyperlinkDetector { + + @Override + protected List<IHyperlink> detectHyperlinks(ITextViewer textViewer, String content, int index, int contentOffset) { + List<IHyperlink> result = new ArrayList<IHyperlink>(); + TaskRepository currentRepository = getTaskRepository(textViewer); + final IHyperlink[] currentRepositoryLinks = detectHyperlinks(currentRepository, content, index, contentOffset); + if (currentRepositoryLinks != null && currentRepositoryLinks.length > 0) { + result.addAll(Arrays.asList(currentRepositoryLinks)); + Set<Region> currentRepositoryRegions = new HashSet<Region>(); + for (IHyperlink link : currentRepositoryLinks) { + currentRepositoryRegions.add(getRegion(link)); + } + List<TaskRepository> otherRepositories = getTaskRepositories(textViewer); + otherRepositories.remove(currentRepository); + for (final TaskRepository repository : otherRepositories) { + final IHyperlink[] links = detectHyperlinks(repository, content, index, contentOffset); + if (links != null) { + for (IHyperlink link : links) { + // prevent highlighting text that is not already a link for the current repository + if (currentRepositoryRegions.contains(getRegion(link))) { + result.add(link); + } + } + } + } + } + if (result.isEmpty()) { + return null; + } + return result; + } + + protected Region getRegion(IHyperlink link) { + if (link.getHyperlinkRegion() instanceof Region) { + return (Region) link.getHyperlinkRegion(); + } else { + return new Region(link.getHyperlinkRegion().getOffset(), link.getHyperlinkRegion().getLength()); + } + } + + @Override + protected List<TaskRepository> getTaskRepositories(ITextViewer textViewer) { + return TasksUi.getRepositoryManager().getAllRepositories(); + } + +} 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 849a3459e..d971b5843 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 @@ -35,32 +35,36 @@ public class TaskHyperlinkDetector extends AbstractTaskHyperlinkDetector { @Override protected List<IHyperlink> detectHyperlinks(ITextViewer textViewer, final String content, final int index, final int contentOffset) { - List<IHyperlink> result = null; + List<IHyperlink> result = new ArrayList<IHyperlink>(); for (final TaskRepository repository : getTaskRepositories(textViewer)) { - final AbstractRepositoryConnectorUi connectorUi = getConnectorUi(repository); - if (connectorUi == null) { - continue; + final IHyperlink[] links = detectHyperlinks(repository, content, index, contentOffset); + if (links != null && links.length > 0) { + result.addAll(Arrays.asList(links)); } - final IHyperlink[][] links = new IHyperlink[1][]; - SafeRunnable.run(new ISafeRunnable() { - - public void handleException(Throwable exception) { - } + } + if (result.isEmpty()) { + return null; + } + return result; + } - public void run() throws Exception { - final ITask task = (ITask) getAdapter(ITask.class); - links[0] = connectorUi.findHyperlinks(repository, task, content, index, contentOffset); - } + protected IHyperlink[] detectHyperlinks(final TaskRepository repository, final String content, final int index, + final int contentOffset) { + final AbstractRepositoryConnectorUi connectorUi = getConnectorUi(repository); + if (connectorUi == null) { + return null; + } + final IHyperlink[][] links = new IHyperlink[1][]; + SafeRunnable.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + } - }); - if (links[0] != null && links[0].length > 0) { - if (result == null) { - result = new ArrayList<IHyperlink>(); - } - result.addAll(Arrays.asList(links[0])); + public void run() throws Exception { + final ITask task = (ITask) getAdapter(ITask.class); + links[0] = connectorUi.findHyperlinks(repository, task, content, index, contentOffset); } - } - return result; + }); + return links[0]; } protected AbstractRepositoryConnectorUi getConnectorUi(TaskRepository repository) { |