| /******************************************************************************* |
| * Copyright (c) 2004, 2008 Tasktop Technologies and others. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * https://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Tasktop Technologies - initial API and implementation |
| * Eugene Kuleshov - improvements |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.tasks.ui; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IResource; |
| 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.hyperlink.AbstractHyperlinkDetector; |
| import org.eclipse.jface.text.hyperlink.IHyperlink; |
| import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; |
| import org.eclipse.mylyn.tasks.core.TaskRepository; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * Base class for hyperlink detectors that provides methods for extracting text from an {@link ITextViewer}. |
| * |
| * @author Rob Elves |
| * @author Steffen Pingel |
| * @author Eugene Kuleshov |
| * @author Terry Hon |
| * @since 3.1 |
| */ |
| public abstract class AbstractTaskHyperlinkDetector extends AbstractHyperlinkDetector { |
| |
| /** |
| * @since 3.1 |
| */ |
| public AbstractTaskHyperlinkDetector() { |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) { |
| IDocument document = textViewer.getDocument(); |
| if (document == null || document.getLength() == 0) { |
| return null; |
| } |
| |
| String content; |
| int contentOffset; |
| int index; |
| try { |
| if (region.getLength() == 0) { |
| // expand the region to include the whole line |
| IRegion lineInfo = document.getLineInformationOfOffset(region.getOffset()); |
| int lineLength = lineInfo.getLength(); |
| int lineOffset = lineInfo.getOffset(); |
| int lineEnd = lineOffset + lineLength; |
| int regionEnd = region.getOffset() + region.getLength(); |
| if (lineOffset < region.getOffset()) { |
| int regionLength = Math.max(regionEnd, lineEnd) - lineOffset; |
| contentOffset = lineOffset; |
| content = document.get(lineOffset, 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); |
| index = 0; |
| } |
| } else { |
| content = document.get(region.getOffset(), region.getLength()); |
| contentOffset = region.getOffset(); |
| index = -1; |
| } |
| } catch (BadLocationException ex) { |
| return null; |
| } |
| |
| List<IHyperlink> hyperlinks = detectHyperlinks(textViewer, content, index, contentOffset); |
| 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()]); |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| protected abstract List<IHyperlink> detectHyperlinks(ITextViewer textViewer, String content, int index, |
| int contentOffset); |
| |
| private boolean isInRegion(IRegion detectInRegion, IRegion hyperlinkRegion) { |
| return detectInRegion.getOffset() >= hyperlinkRegion.getOffset() |
| && detectInRegion.getOffset() <= hyperlinkRegion.getOffset() + hyperlinkRegion.getLength(); |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| protected List<TaskRepository> getTaskRepositories(ITextViewer textViewer) { |
| List<TaskRepository> repositories = new ArrayList<TaskRepository>(); |
| TaskRepository selectedRepository = getTaskRepository(textViewer); |
| if (selectedRepository != null) { |
| repositories.add(selectedRepository); |
| } else { |
| repositories.addAll(TasksUi.getRepositoryManager().getAllRepositories()); |
| } |
| return repositories; |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| protected TaskRepository getTaskRepository(ITextViewer textViewer) { |
| TaskRepository repository = (TaskRepository) getAdapter(TaskRepository.class); |
| if (repository != null) { |
| return repository; |
| } |
| |
| IResource resource = (IResource) getAdapter(IResource.class); |
| if (resource == null) { |
| // use currently active editor (if any) |
| IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| if (window != null) { |
| IWorkbenchPage activePage = window.getActivePage(); |
| if (activePage != null) { |
| IWorkbenchPart part = activePage.getActivePart(); |
| if (part instanceof IEditorPart) { |
| IEditorInput input = ((IEditorPart) part).getEditorInput(); |
| if (input != null) { |
| resource = (IResource) input.getAdapter(IResource.class); |
| } |
| } |
| } |
| } |
| } |
| if (resource != null) { |
| return TasksUiPlugin.getDefault().getRepositoryForResource(resource); |
| } |
| return null; |
| } |
| |
| } |