blob: b47133e2eea4c6dcd41c6be9592776566db95df0 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}