/*******************************************************************************
* Copyright (c) 2013 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.el.ui.internal.info;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil;
import org.eclipse.jdt.internal.ui.actions.SimpleSelectionProvider;
import org.eclipse.jdt.internal.ui.infoviews.JavadocView;
import org.eclipse.jdt.internal.ui.text.java.hover.JavadocBrowserInformationControlInput;
import org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover;
import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
import org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks;
import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.actions.OpenAttachedJavadocAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.internal.text.html.BrowserInformationControl;
import org.eclipse.jface.internal.text.html.BrowserInformationControlInput;
import org.eclipse.jface.internal.text.html.BrowserInput;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IInformationControlExtension4;
import org.eclipse.jface.text.IInputChangedListener;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.xml.ui.internal.taginfo.XMLTagInfoHoverProcessor;
import org.jboss.tools.common.el.ui.ElUiPlugin;
import org.jboss.tools.common.el.ui.ca.ELProposalProcessor;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.filesystems.impl.JarSystemImpl;
import org.osgi.framework.Bundle;
/**
* A utility class for Hover Info and Content Assist Additional Info creation
*
* @author Victor V. Rubezhny
*
*/
@SuppressWarnings("restriction")
public class ELInfoHover extends XMLTagInfoHoverProcessor {
private IInformationControlCreator fHoverControlCreator;
private IInformationControlCreator fPresenterControlCreator;
/*
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover#getInformationPresenterControlCreator()
*/
public IInformationControlCreator getInformationPresenterControlCreator() {
final boolean[] browserInformationControlAvailable = new boolean[] {false};
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
Shell shell= JavaPlugin.getActiveWorkbenchShell();
browserInformationControlAvailable[0] = (shell != null && BrowserInformationControl.isAvailable(shell));
}
});
if (!browserInformationControlAvailable[0])
return null;
if (fPresenterControlCreator == null)
fPresenterControlCreator= new PresenterControlCreator(getSite());
return fPresenterControlCreator;
}
/*
* @see ITextHoverExtension#getHoverControlCreator()
*/
@Override
public IInformationControlCreator getHoverControlCreator() {
if (fHoverControlCreator == null)
fHoverControlCreator= new HoverControlCreator(getInformationPresenterControlCreator(), null);
return fHoverControlCreator;
}
public static Object getHoverInfo(String info, IProgressMonitor monitor) {
if (info != null && info.length() > 0) {
StringBuffer buffer= new StringBuffer();
HTMLPrinter.insertPageProlog(buffer, 0, getCSSStyles());
buffer.append(info.trim());
HTMLPrinter.addPageEpilog(buffer);
return new ELBrowserInformationControlInput(null, null, processLinks(buffer.toString()), 0);
}
return null;
}
public static Object getHoverInfo(IJavaElement[] javaElements, IProgressMonitor monitor) {
if (javaElements != null && javaElements.length > 0) {
Arrays.sort(javaElements, ELProposalProcessor.CASE_INSENSITIVE_ORDER);
return new ELBrowserInformationControlInput(null, javaElements,
processLinks(extractProposalContextInfo(javaElements)), 0);
}
return null;
}
public static Object getHoverInfo(String baseName, String propertyName, Object allObjects, IProgressMonitor monitor) {
String info = extractProposalContextInfo(baseName, propertyName, allObjects);
return info != null ? new ELBrowserInformationControlInput(null, null, processLinks(info), 0) : null;
}
public static IWorkbenchSite getSite() {
IWorkbench workBench = ElUiPlugin.getDefault() == null ? null : ElUiPlugin.getDefault().getWorkbench();
IWorkbenchWindow window = workBench == null ? null : workBench.getActiveWorkbenchWindow();
IWorkbenchPage page = window == null ? null : window.getActivePage();
IWorkbenchPart part = page == null ? null : page.getActivePart();
return part == null ? null : part.getSite();
}
/*
* Extracts the additional proposal information based on Javadoc for the
* stored IJavaElement objects
*/
private static String extractProposalContextInfo(IJavaElement[] elements) {
int nResults = elements.length;
StringBuffer buffer = new StringBuffer();
boolean hasContents = false;
IJavaElement element = null;
if (nResults > 1) {
for (int i = 0; i < elements.length; i++) {
if (elements[i] == null)
continue;
if (elements[i] instanceof IMember
|| elements[i].getElementType() == IJavaElement.LOCAL_VARIABLE
|| elements[i].getElementType() == IJavaElement.TYPE_PARAMETER) {
addFullInfo(buffer, elements[i]);
buffer.append("<br/>"); //$NON-NLS-1$
hasContents = true;
}
}
} else {
element = elements[0];
if (element instanceof IMember
|| element.getElementType() == IJavaElement.LOCAL_VARIABLE
|| element.getElementType() == IJavaElement.TYPE_PARAMETER) {
addFullInfo(buffer, element);
hasContents = true;
}
}
if (!hasContents || buffer.length() == 0)
return null;
HTMLPrinter.insertPageProlog(buffer, 0, getCSSStyles());
HTMLPrinter.addPageEpilog(buffer);
return buffer.toString();
}
/*
* Adds full information to the additional proposal information
*
* @param buffer
*
* @param element
*
* @return
*/
private static void addFullInfo(StringBuffer buffer, IJavaElement element) {
if (element instanceof IMember) {
IMember member = (IMember) element;
HTMLPrinter.addSmallHeader(buffer, getInfoText(member));
Reader reader = null;
try {
String content = JavadocContentAccess2.getHTMLContent(member,
true);
reader = content == null ? null : new StringReader(content);
} catch (JavaModelException ex) {
ElUiPlugin.getDefault().logError(ex);
} catch (CoreException e) {
ElUiPlugin.getDefault().logError(e);
}
if (reader == null) {
reader = new StringReader(Messages.NO_JAVADOC);
}
if (reader != null) {
buffer.append("<br/>"); //$NON-NLS-1$
buffer.append(HTMLPrinter.read(reader));
}
} else if (element.getElementType() == IJavaElement.LOCAL_VARIABLE
|| element.getElementType() == IJavaElement.TYPE_PARAMETER) {
HTMLPrinter.addSmallHeader(buffer, getInfoText(element));
}
}
private static final long LABEL_FLAGS = JavaElementLabels.ALL_FULLY_QUALIFIED
| JavaElementLabels.M_PRE_RETURNTYPE
| JavaElementLabels.M_PARAMETER_TYPES
| JavaElementLabels.M_PARAMETER_NAMES
| JavaElementLabels.M_EXCEPTIONS
| JavaElementLabels.F_PRE_TYPE_SIGNATURE
| JavaElementLabels.M_PRE_TYPE_PARAMETERS
| JavaElementLabels.T_TYPE_PARAMETERS
| JavaElementLabels.USE_RESOLVED;
private static final long LOCAL_VARIABLE_FLAGS = LABEL_FLAGS
& ~JavaElementLabels.F_FULLY_QUALIFIED
| JavaElementLabels.F_POST_QUALIFIED;
private static final long TYPE_PARAMETER_FLAGS = LABEL_FLAGS
| JavaElementLabels.TP_POST_QUALIFIED;
/*
* Returns the label for the IJavaElement objects
*/
private static String getInfoText(IJavaElement element) {
long flags;
switch (element.getElementType()) {
case IJavaElement.LOCAL_VARIABLE:
flags = LOCAL_VARIABLE_FLAGS;
break;
case IJavaElement.TYPE_PARAMETER:
flags = TYPE_PARAMETER_FLAGS;
break;
default:
flags = LABEL_FLAGS;
break;
}
return JavadocHover.getImageAndLabel(element, true, JavaElementLinks.getElementLabel(element, flags, true));
}
/*
* Extracts the additional proposal information based on Javadoc for the
* stored IJavaElement objects
*/
private static String extractProposalContextInfo(
String baseName, String propertyName, Object allObjects) {
Assert.isTrue(allObjects instanceof List<?>);
String info = getELMessagesHoverInternal(
baseName, propertyName, (List<XModelObject>) allObjects);
if (info == null) return null;
StringBuffer buffer = new StringBuffer();
buffer.append(info);
if (buffer.length() == 0) return null;
HTMLPrinter.insertPageProlog(buffer, 0, getCSSStyles());
HTMLPrinter.addPageEpilog(buffer);
return buffer.toString();
}
public static String getELMessagesHoverInternal(String baseName, String propertyName, List<XModelObject> objects) {
StringBuffer buffer= new StringBuffer();
if (propertyName != null && propertyName.length() > 0)
buffer.append(MessageFormat.format(Messages.ELInfoHover_propertyName,
propertyName));
if (baseName != null && baseName.length() > 0)
buffer.append(MessageFormat.format(Messages.ELInfoHover_baseName,
baseName));
if (objects != null) {
boolean firstValue = true;
for (XModelObject o : objects) {
IFile propFile = (IFile)o.getAdapter(IFile.class);
String propFilePath = null;
if (propFile != null) {
propFilePath = propFile.getFullPath().toString();
} else {
XModelObject parent = o.getFileType() == XModelObject.FILE ? o : o.getParent();
String path = parent.getPath();
while (parent != null && parent.getFileType() != XModelObject.SYSTEM) {
parent = parent.getParent();
}
if (parent instanceof JarSystemImpl) {
String sysPath = parent.getPath();
path = path.substring(sysPath.length());
String jarPath = ((JarSystemImpl) parent).getLocation();
IResource jar = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(jarPath));
if (jar != null) {
jarPath = jar.getFullPath().toString();
}
propFilePath = jarPath + "!" + path; //$NON-NLS-1$
}
}
buffer.append(Messages.ELInfoHover_newLine);
if (!firstValue) buffer.append(Messages.ELInfoHover_newLine);
else firstValue = false;
buffer.append(MessageFormat.format(Messages.ELInfoHover_resourceBundle,
propFilePath != null ? propFilePath : Messages.ELInfoHover_resourceBundleNotDefined));
if (propertyName != null) {
String value = o.get("VALUE"); //$NON-NLS-1$
boolean addCut = false;
if (value != null) {
if (value.length() > 100) {
// Get first words of value
int lastSpace = value.lastIndexOf(' ', 99);
if (lastSpace != -1) {
value = value.substring(0, lastSpace);
} else { // cut as is
value = value.substring(0, 100);
}
addCut = true;
}
}
buffer.append(Messages.ELInfoHover_newLine);
buffer.append(MessageFormat.format(Messages.ELInfoHover_resourceBundlePropertyValue,
value != null ? value : Messages.ELInfoHover_resourceBundlePropertyValueNotDefined,
addCut ? Messages.ELInfoHover_treeDots : "")); //$NON-NLS-1$
}
}
}
return buffer.length() == 0 ? null : buffer.toString();
}
private static final String[] PROTOCOLS = {
JavaElementLinks.JAVADOC_VIEW_SCHEME,
JavaElementLinks.JAVADOC_SCHEME,
JavaElementLinks.OPEN_LINK_SCHEME,
"http", //$NON-NLS-1$
"https" //$NON-NLS-1$
};
protected static String processLinks(String html) {
if (html == null)
return ""; //$NON-NLS-1$
String text;
try {
HTMLAnchorProcessor reader= new HTMLAnchorProcessor(new StringReader(html), PROTOCOLS);
text= reader.getString();
reader.close();
} catch (IOException e) {
text= ""; //$NON-NLS-1$
}
return text;
}
private static String fCSSStyles;
/**
* Returns the style information for displaying HTML content.
*
* @return the CSS styles
*/
private static String getCSSStyles() {
if (fCSSStyles == null) {
Bundle bundle= Platform.getBundle(ElUiPlugin.PLUGIN_ID);
URL url= bundle.getEntry("/resources/css/ELInfoHoverStyleSheet.css"); //$NON-NLS-1$
if (url != null) {
BufferedReader reader= null;
try {
url= FileLocator.toFileURL(url);
reader= new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder buffer= new StringBuilder(200);
String line= reader.readLine();
while (line != null) {
buffer.append(line);
buffer.append('\n');
line= reader.readLine();
}
fCSSStyles= buffer.toString();
} catch (IOException ex) {
ElUiPlugin.getDefault().logError(ex);
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
}
}
String css= fCSSStyles;
if (css != null) {
FontData fontData= JFaceResources.getFontRegistry().getFontData(JFaceResources.DIALOG_FONT)[0];
css= HTMLPrinter.convertTopLevelFont(css, fontData);
}
return css;
}
/**
* Hover control creator.
*/
public static final class HoverControlCreator extends AbstractReusableInformationControlCreator {
/**
* The information presenter control creator.
*/
private final IInformationControlCreator fInformationPresenterControlCreator;
private String fAffordance = null;
/**
* @param informationPresenterControlCreator control creator for enriched hover
*/
public HoverControlCreator(IInformationControlCreator informationPresenterControlCreator, String affordance) {
fInformationPresenterControlCreator= informationPresenterControlCreator;
fAffordance = affordance;
}
/*
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
*/
@Override
public IInformationControl doCreateInformationControl(Shell parent) {
if (BrowserInformationControl.isAvailable(parent)) {
BrowserInformationControl iControl = new BrowserInformationControl(parent, null,
fAffordance == null ? Messages.hover_affordance : fAffordance) {
/*
* @see org.eclipse.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
*/
@Override
public IInformationControlCreator getInformationPresenterControlCreator() {
return fInformationPresenterControlCreator;
}
};
addLinkListener(iControl);
return iControl;
} else {
return new DefaultInformationControl(parent, fAffordance == null ? Messages.hover_affordance : fAffordance);
}
}
/*
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#canReuse(org.eclipse.jface.text.IInformationControl)
*/
@Override
public boolean canReuse(IInformationControl control) {
if (!super.canReuse(control))
return false;
if (control instanceof IInformationControlExtension4) {
((IInformationControlExtension4)control).setStatusText(fAffordance == null ? Messages.hover_affordance : fAffordance);
}
return true;
}
}
/**
* Presenter control creator.
*/
public static final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
private final IWorkbenchSite fSite;
/**
* Creates a new PresenterControlCreator.
*
* @param site the site or <code>null</code> if none
*/
public PresenterControlCreator(IWorkbenchSite site) {
fSite= site;
}
/*
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
*/
@Override
public IInformationControl doCreateInformationControl(Shell parent) {
if (BrowserInformationControl.isAvailable(parent)) {
ToolBarManager tbm= new ToolBarManager(SWT.FLAT);
BrowserInformationControl iControl= new BrowserInformationControl(parent, null, tbm);
final BackAction backAction= new BackAction(iControl);
backAction.setEnabled(false);
tbm.add(backAction);
final ForwardAction forwardAction= new ForwardAction(iControl);
tbm.add(forwardAction);
forwardAction.setEnabled(false);
final ShowInJavadocViewAction showInJavadocViewAction= new ShowInJavadocViewAction(iControl);
tbm.add(showInJavadocViewAction);
final OpenDeclarationAction openDeclarationAction= new OpenDeclarationAction(iControl);
tbm.add(openDeclarationAction);
final SimpleSelectionProvider selectionProvider= new SimpleSelectionProvider();
if (fSite != null) {
OpenAttachedJavadocAction openAttachedJavadocAction= new OpenAttachedJavadocAction(fSite);
openAttachedJavadocAction.setSpecialSelectionProvider(selectionProvider);
openAttachedJavadocAction.setImageDescriptor(JavaPluginImages.DESC_ELCL_OPEN_BROWSER);
openAttachedJavadocAction.setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_OPEN_BROWSER);
selectionProvider.addSelectionChangedListener(openAttachedJavadocAction);
selectionProvider.setSelection(new StructuredSelection());
tbm.add(openAttachedJavadocAction);
}
IInputChangedListener inputChangeListener= new IInputChangedListener() {
public void inputChanged(Object newInput) {
backAction.update();
forwardAction.update();
if (newInput == null) {
selectionProvider.setSelection(new StructuredSelection());
} else if (newInput instanceof BrowserInformationControlInput) {
BrowserInformationControlInput input= (BrowserInformationControlInput) newInput;
Object inputElement= input.getInputElement();
selectionProvider.setSelection(new StructuredSelection(inputElement));
boolean isJavaElementInput= inputElement instanceof IJavaElement;
showInJavadocViewAction.setEnabled(isJavaElementInput);
openDeclarationAction.setEnabled(isJavaElementInput);
}
}
};
iControl.addInputChangeListener(inputChangeListener);
tbm.update(true);
addLinkListener(iControl);
return iControl;
} else {
return new DefaultInformationControl(parent, true);
}
}
}
private static void addLinkListener(final BrowserInformationControl control) {
control.addLocationListener(new LocationListener() {
@Override
public void changing(LocationEvent event) {
String loc= event.location;
if ("about:blank".equals(loc)) { //$NON-NLS-1$
return;
}
event.doit= false;
if (loc.startsWith("about:")) { //$NON-NLS-1$
// Relative links should be handled via head > base tag.
// If no base is available, links just won't work.
return;
}
URI uri= null;
try {
uri= new URI(loc);
} catch (URISyntaxException e) {
ElUiPlugin.getDefault().logError(e);
return;
}
String scheme= uri == null ? null : uri.getScheme();
if (JavaElementLinks.JAVADOC_VIEW_SCHEME.equals(scheme)) {
IJavaElement linkTarget= JavaElementLinks.parseURI(uri);
if (linkTarget == null)
return;
handleJavadocViewLink(linkTarget);
} else if (JavaElementLinks.JAVADOC_SCHEME.equals(scheme)) {
IJavaElement linkTarget= JavaElementLinks.parseURI(uri);
if (linkTarget == null)
return;
handleInlineJavadocLink(linkTarget);
} else if (JavaElementLinks.OPEN_LINK_SCHEME.equals(scheme)) {
IJavaElement linkTarget= JavaElementLinks.parseURI(uri);
if (linkTarget == null)
return;
handleDeclarationLink(linkTarget);
} else if (scheme != null && (scheme.toLowerCase().equalsIgnoreCase("http") || //$NON-NLS-1$
scheme.toLowerCase().equalsIgnoreCase("https"))) { //$NON-NLS-1$
try {
if (handleExternalLink(new URL(loc), event.display, true))
return;
event.doit= true;
} catch (MalformedURLException e) {
ElUiPlugin.getDefault().logError(e);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleJavadocViewLink(org.eclipse.jdt.core.IJavaElement)
*/
public void handleJavadocViewLink(IJavaElement linkTarget) {
control.notifyDelayedInputChange(null);
control.setVisible(false);
control.dispose();
try {
JavadocView view= (JavadocView) JavaPlugin.getActivePage().showView(JavaUI.ID_JAVADOC_VIEW);
view.setInput(linkTarget);
} catch (PartInitException e) {
ElUiPlugin.getDefault().logError(e);
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleInlineJavadocLink(org.eclipse.jdt.core.IJavaElement)
*/
public void handleInlineJavadocLink(IJavaElement linkTarget) {
JavadocBrowserInformationControlInput hoverInfo= JavadocHover.getHoverInfo(new IJavaElement[] { linkTarget }, null, null, (JavadocBrowserInformationControlInput) control.getInput());
if (control.hasDelayedInputChangeListener())
control.notifyDelayedInputChange(hoverInfo);
else
control.setInput(hoverInfo);
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleDeclarationLink(org.eclipse.jdt.core.IJavaElement)
*/
public void handleDeclarationLink(IJavaElement linkTarget) {
control.notifyDelayedInputChange(null);
control.dispose(); //FIXME: should have protocol to hide, rather than dispose
try {
JavadocHover.openDeclaration(linkTarget);
} catch (PartInitException e) {
ElUiPlugin.getDefault().logError(e);
} catch (JavaModelException e) {
ElUiPlugin.getDefault().logError(e);
}
}
boolean handleExternalLink(URL url, Display display, boolean openInExternalBrowser) {
control.notifyDelayedInputChange(null);
control.dispose();
// Open attached Javadoc links
if (openInExternalBrowser)
OpenBrowserUtil.openExternal(url, display);
else
OpenBrowserUtil.open(url, display);
return true;
}
public void changed(LocationEvent event) {
}
});
}
/**
* Action to go back to the previous input in the hover control.
*
* @since 3.4
*/
private static final class BackAction extends Action {
private final BrowserInformationControl fInfoControl;
public BackAction(BrowserInformationControl infoControl) {
fInfoControl= infoControl;
setText(Messages.ELInfoHover_back);
ISharedImages images= PlatformUI.getWorkbench().getSharedImages();
setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_BACK));
setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED));
update();
}
@Override
public void run() {
BrowserInformationControlInput previous= (BrowserInformationControlInput) fInfoControl.getInput().getPrevious();
if (previous != null) {
fInfoControl.setInput(previous);
}
}
public void update() {
BrowserInformationControlInput current= fInfoControl.getInput();
if (current != null && current.getPrevious() != null) {
BrowserInput previous= current.getPrevious();
setToolTipText(org.eclipse.jdt.internal.corext.util.Messages.format(Messages.ELInfoHover_back_toElement_toolTip, BasicElementLabels.getJavaElementName(previous.getInputName())));
setEnabled(true);
} else {
setToolTipText(Messages.ELInfoHover_back);
setEnabled(false);
}
}
}
/**
* Action to go forward to the next input in the hover control.
*
* @since 3.4
*/
private static final class ForwardAction extends Action {
private final BrowserInformationControl fInfoControl;
public ForwardAction(BrowserInformationControl infoControl) {
fInfoControl= infoControl;
setText(Messages.ELInfoHover_forward);
ISharedImages images= PlatformUI.getWorkbench().getSharedImages();
setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));
setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD_DISABLED));
update();
}
@Override
public void run() {
BrowserInformationControlInput next= (BrowserInformationControlInput) fInfoControl.getInput().getNext();
if (next != null) {
fInfoControl.setInput(next);
}
}
public void update() {
BrowserInformationControlInput current= fInfoControl.getInput();
if (current != null && current.getNext() != null) {
setToolTipText(org.eclipse.jdt.internal.corext.util.Messages.format(Messages.ELInfoHover_forward_toElement_toolTip, BasicElementLabels.getJavaElementName(current.getNext().getInputName())));
setEnabled(true);
} else {
setToolTipText(Messages.ELInfoHover_forward_toolTip);
setEnabled(false);
}
}
}
/**
* Action that shows the current hover contents in the Javadoc view.
*
* @since 3.4
*/
private static final class ShowInJavadocViewAction extends Action {
private final BrowserInformationControl fInfoControl;
public ShowInJavadocViewAction(BrowserInformationControl infoControl) {
fInfoControl= infoControl;
setText(Messages.ELInfoHover_showInJavadoc);
setImageDescriptor(JavaPluginImages.DESC_OBJS_JAVADOCTAG); //TODO: better image
}
/*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
JavadocBrowserInformationControlInput infoInput= (JavadocBrowserInformationControlInput) fInfoControl.getInput(); //TODO: check cast
fInfoControl.notifyDelayedInputChange(null);
fInfoControl.dispose(); //FIXME: should have protocol to hide, rather than dispose
try {
JavadocView view= (JavadocView) JavaPlugin.getActivePage().showView(JavaUI.ID_JAVADOC_VIEW);
view.setInput(infoInput);
} catch (PartInitException e) {
ElUiPlugin.getDefault().logError(e);
}
}
}
/**
* Action that opens the current hover input element.
*
* @since 3.4
*/
private static final class OpenDeclarationAction extends Action {
private final BrowserInformationControl fInfoControl;
public OpenDeclarationAction(BrowserInformationControl infoControl) {
fInfoControl= infoControl;
setText(Messages.ELInfoHover_openDeclaration);
JavaPluginImages.setLocalImageDescriptors(this, "goto_input.gif"); //$NON-NLS-1$ //TODO: better images
}
/*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
JavadocBrowserInformationControlInput infoInput= (JavadocBrowserInformationControlInput) fInfoControl.getInput(); //TODO: check cast
fInfoControl.notifyDelayedInputChange(null);
fInfoControl.dispose(); //FIXME: should have protocol to hide, rather than dispose
try {
JavadocHover.openDeclaration(infoInput.getElement());
} catch (PartInitException e) {
ElUiPlugin.getDefault().logError(e);
} catch (JavaModelException e) {
ElUiPlugin.getDefault().logError(e);
}
}
}
}