|
|
/*******************************************************************************
* Copyright (c) 2004, 2009 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
* Frank Becker - improvements
*******************************************************************************/
package org.eclipse.mylyn.tasks.ui;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.MultipleHyperlinkPresenter;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.tasks.core.TaskList;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.editors.Messages;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
/**
* A hyperlink presenter that displays a tooltip when hovering over a {@link TaskHyperlink}.
*
* @author Steffen Pingel
* @author Frank Becker
* @since 3.1
*/
public final class TaskHyperlinkPresenter extends MultipleHyperlinkPresenter {
private IRegion activeRegion;
/**
* Stores which task a tooltip is being displayed for. It is used to avoid having the same tooltip being set
* multiple times while you move the mouse over a task hyperlink (bug#209409)
*/
private ITask currentTask;
private TaskHyperlink currentTaskHyperlink;
private ITextViewer textViewer;
private String oldToolTip;
private boolean restoreToolTip;
// TODO e3.7 remove all references to delegate and replace with calls to super methods
private final MultipleHyperlinkPresenter delegate;
private boolean errorLogged;
/**
* @see DefaultHyperlinkPresenter#DefaultHyperlinkPresenter(IPreferenceStore)
*/
public TaskHyperlinkPresenter(IPreferenceStore store) {
super(store);
delegate = new MultipleHyperlinkPresenter(store);
}
/**
* @see DefaultHyperlinkPresenter#DefaultHyperlinkPresenter(RGB)
*/
public TaskHyperlinkPresenter(RGB color) {
super(color);
delegate = new MultipleHyperlinkPresenter(color);
}
@Override
public void install(ITextViewer textViewer) {
this.textViewer = textViewer;
delegate.install(textViewer);
}
@Override
public void uninstall() {
hideHyperlinks();
this.textViewer = null;
delegate.uninstall();
}
@SuppressWarnings("unchecked")
@Override
public void applyTextPresentation(TextPresentation textPresentation) {
delegate.applyTextPresentation(textPresentation);
// decorate hyperlink as strike-through if task is completed, this is now also handled by TaskHyperlinkTextPresentationManager
if (activeRegion != null && currentTask != null && currentTask.isCompleted()) {
Iterator<StyleRange> styleRangeIterator = textPresentation.getAllStyleRangeIterator();
while (styleRangeIterator.hasNext()) {
StyleRange styleRange = styleRangeIterator.next();
if (activeRegion.getOffset() == styleRange.start && activeRegion.getLength() == styleRange.length) {
styleRange.strikeout = true;
break;
}
}
}
}
// TODO e3.7 remove method
@Override
public void showHyperlinks(IHyperlink[] hyperlinks) {
showHyperlinks(hyperlinks, false);
}
// TODO e3.7 add @Override annotation
public void showHyperlinks(IHyperlink[] hyperlinks, boolean takesFocusWhenVisible) {
activeRegion = null;
// show task name in tooltip
if (hyperlinks.length == 1 && hyperlinks[0] instanceof TaskHyperlink) {
TaskHyperlink hyperlink = (TaskHyperlink) hyperlinks[0];
TaskList taskList = TasksUiPlugin.getTaskList();
String repositoryUrl = hyperlink.getRepository().getRepositoryUrl();
ITask task = taskList.getTask(repositoryUrl, hyperlink.getTaskId());
if (task == null) {
task = taskList.getTaskByKey(repositoryUrl, hyperlink.getTaskId());
}
if (!hyperlinks[0].equals(currentTaskHyperlink)) {
currentTaskHyperlink = (TaskHyperlink) hyperlinks[0];
currentTask = task;
activeRegion = hyperlink.getHyperlinkRegion();
if (textViewer != null && textViewer.getTextWidget() != null
&& !textViewer.getTextWidget().isDisposed()) {
oldToolTip = textViewer.getTextWidget().getToolTipText();
restoreToolTip = true;
if (task == null) {
String taskLabel = TasksUiInternal.getTaskPrefix(hyperlink.getRepository().getConnectorKind());
taskLabel += currentTaskHyperlink.getTaskId();
textViewer.getTextWidget().setToolTipText(
NLS.bind(Messages.TaskHyperlinkPresenter_Not_In_Task_List, taskLabel));
} else if (task.getTaskKey() == null) {
textViewer.getTextWidget().setToolTipText(task.getSummary());
} else {
textViewer.getTextWidget().setToolTipText(task.getTaskKey() + ": " + task.getSummary()); //$NON-NLS-1$
}
}
}
}
// invoke super implementation
try {
// Eclipse 3.7
Method method = MultipleHyperlinkPresenter.class.getDeclaredMethod("showHyperlinks", //$NON-NLS-1$
IHyperlink[].class, boolean.class);
method.invoke(delegate, hyperlinks, takesFocusWhenVisible);
} catch (NoSuchMethodException e) {
// Eclipse 3.6 and earlier
delegate.showHyperlinks(hyperlinks);
} catch (Exception e) {
if (!errorLogged) {
errorLogged = true;
StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
"Unexpected error while displaying hyperlink", e)); //$NON-NLS-1$
}
}
}
@Override
public void hideHyperlinks() {
if (currentTaskHyperlink != null) {
if (restoreToolTip && textViewer != null && textViewer.getTextWidget() != null
&& !textViewer.getTextWidget().isDisposed()) {
textViewer.getTextWidget().setToolTipText(oldToolTip);
restoreToolTip = false;
}
currentTaskHyperlink = null;
currentTask = null;
}
delegate.hideHyperlinks();
}
@Override
public boolean canHideHyperlinks() {
return delegate.canHideHyperlinks();
}
@Override
public boolean canShowMultipleHyperlinks() {
return delegate.canShowMultipleHyperlinks();
}
@Override
public void documentAboutToBeChanged(DocumentEvent event) {
delegate.documentAboutToBeChanged(event);
}
@Override
public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
delegate.inputDocumentAboutToBeChanged(oldInput, newInput);
}
@Override
public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
delegate.inputDocumentChanged(oldInput, newInput);
}
@Override
public void propertyChange(PropertyChangeEvent event) {
delegate.propertyChange(event);
}
@Override
public void setColor(Color color) {
delegate.setColor(color);
}
}
|