blob: 04faf99dd3c51898b76d78cdfa105e2a1693161d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* This class is taken from org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover
*
* Contributors:
* IBM Corporation - initial API and implementation
* Genady Beryozkin <eclipse@genady.org> - [hovering] tooltip for constant string does not show constant value - https://bugs.eclipse.org/bugs/show_bug.cgi?id=85382
* Stephan Herrmann - Contribution for Bug 403917 - [1.8] Render TYPE_USE annotations in Javadoc hover/view
*******************************************************************************/
package org.eclipse.ease.ui.help.hovers.internal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import org.eclipse.ease.Logger;
import org.eclipse.ease.tools.StringTools;
import org.eclipse.ease.ui.Activator;
import org.eclipse.ease.ui.help.hovers.IHoverContentProvider;
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.HTMLPrinter;
import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
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.text.TextPresentation;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
/**
* Provides a javadoc-like hover info.
*/
public class JavaDocLikeHover {
/**
* The symbolic font name for the font used to display Module documentation (value <code>"org.eclipse.ease.ui.moduledocfont"</code>).
*
*/
public final static String APPEARANCE_MODULEDOC_FONT = "org.eclipse.ease.ui.moduledocfont"; //$NON-NLS-1$
public static final String CONSTANT_VALUE_SEPARATOR = " : "; //$NON-NLS-1$
public static class FallbackInformationPresenter extends HTMLTextPresenter {
public FallbackInformationPresenter() {
super(false);
}
@Override
public String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
// FIXME Bug 517576
// final String warningInfo = JavaHoverMessages.JavadocHover_fallback_warning;
final String warningInfo = "NOTE: The SWT Browser widget could not be created. This fallback mode doesn't show links and misses other functionality.";
final String warning = super.updatePresentation(drawable, warningInfo, presentation, maxWidth, maxHeight);
presentation.clear();
final String content = super.updatePresentation(drawable, hoverInfo, presentation, maxWidth, maxHeight);
return content + "\n\n" + warning; //$NON-NLS-1$
}
}
/**
* 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;
// FIXME Bug 517576
// setText(JavaHoverMessages.JavadocHover_back);
setText("Back");
final 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() {
final BrowserInformationControlInput previous = (BrowserInformationControlInput) fInfoControl.getInput().getPrevious();
if (previous != null) {
fInfoControl.setInput(previous);
}
}
public void update() {
final BrowserInformationControlInput current = fInfoControl.getInput();
if ((current != null) && (current.getPrevious() != null)) {
setToolTipText("back to previous");
setEnabled(true);
} else {
setToolTipText("JavaHoverMessages.JavadocHover_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;
// FIXME Bug 517576
// setText(JavaHoverMessages.JavadocHover_forward);
setText("Forward");
final 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() {
final BrowserInformationControlInput next = (BrowserInformationControlInput) fInfoControl.getInput().getNext();
if (next != null) {
fInfoControl.setInput(next);
}
}
public void update() {
final BrowserInformationControlInput current = fInfoControl.getInput();
if ((current != null) && (current.getNext() != null)) {
setToolTipText("forward");
setEnabled(true);
} else {
setToolTipText("JavaHoverMessages.JavadocHover_forward_toolTip");
setEnabled(false);
}
}
}
/**
* Presenter control creator.
*
* @since 3.3
*/
public final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
/*
* @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)) {
final ToolBarManager tbm = new ToolBarManager(SWT.FLAT);
final String font = APPEARANCE_MODULEDOC_FONT;
final BrowserInformationControl iControl = new BrowserInformationControl(parent, font, tbm);
fHoverContent.populateToolbar(iControl, 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 IInputChangedListener inputChangeListener = newInput -> {
backAction.update();
forwardAction.update();
};
iControl.addInputChangeListener(inputChangeListener);
tbm.update(true);
return iControl;
} else {
return new DefaultInformationControl(parent, true);
}
}
}
/**
* Hover control creator.
*
* @since 3.3
*/
public static final class HoverControlCreator extends AbstractReusableInformationControlCreator {
/**
* The information presenter control creator.
*
* @since 3.4
*/
private final IInformationControlCreator fInformationPresenterControlCreator;
/**
* @param informationPresenterControlCreator
* control creator for enriched hover
* @since 3.4
*/
public HoverControlCreator(IInformationControlCreator informationPresenterControlCreator) {
fInformationPresenterControlCreator = informationPresenterControlCreator;
}
/*
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
*/
@Override
public IInformationControl doCreateInformationControl(Shell parent) {
final String tooltipAffordanceString = "Press 'F2' for focus";
if (BrowserInformationControl.isAvailable(parent)) {
final String font = APPEARANCE_MODULEDOC_FONT;
return new BrowserInformationControl(parent, font, tooltipAffordanceString) {
/*
* @see org.eclipse.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
*/
@Override
public IInformationControlCreator getInformationPresenterControlCreator() {
return fInformationPresenterControlCreator;
}
};
} else {
return new DefaultInformationControl(parent, tooltipAffordanceString) {
@Override
public IInformationControlCreator getInformationPresenterControlCreator() {
return parentShell -> new DefaultInformationControl(parentShell, (ToolBarManager) null, new FallbackInformationPresenter());
}
};
}
}
/*
* @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) {
final String tooltipAffordanceString = "Press 'F2' for focus";
((IInformationControlExtension4) control).setStatusText(tooltipAffordanceString);
}
return true;
}
}
/**
* The style sheet (css).
*
* @since 3.4
*/
private static String fgStyleSheet;
/**
* The hover control creator.
*
* @since 3.2
*/
private IInformationControlCreator fHoverControlCreator;
/**
* The presentation control creator.
*
* @since 3.2
*/
private IInformationControlCreator fPresenterControlCreator;
private final IHoverContentProvider fHoverContent;
/**
* @param hoverContent
*/
public JavaDocLikeHover(IHoverContentProvider hoverContent) {
fHoverContent = hoverContent;
}
/*
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover#getInformationPresenterControlCreator()
*
* @since 3.1
*/
public IInformationControlCreator getInformationPresenterControlCreator() {
if (fPresenterControlCreator == null)
fPresenterControlCreator = new PresenterControlCreator();
return fPresenterControlCreator;
}
/*
* @see ITextHoverExtension#getHoverControlCreator()
*
* @since 3.2
*/
public IInformationControlCreator getHoverControlCreator() {
if (fHoverControlCreator == null)
fHoverControlCreator = new HoverControlCreator(getInformationPresenterControlCreator());
return fHoverControlCreator;
}
/**
* Computes the hover info.
*
* @param elements
* the resolved elements
* @param editorInputElement
* the editor input, or <code>null</code>
* @param hoverRegion
* the text range of the hovered word, or <code>null</code>
* @param previousInput
* the previous input, or <code>null</code>
* @return the HTML hover info for the given element(s) or <code>null</code> if no information is available
* @since 3.4
*/
public static BrowserInformationControlInput getHoverInfo(String content, BrowserInformationControlInput previousInput) {
final StringBuffer buffer = new StringBuffer(content);
// HTMLPrinter.addParagraph(buffer, content);
if (buffer.length() > 0) {
HTMLPrinter.insertPageProlog(buffer, 0, getStyleSheet());
HTMLPrinter.addPageEpilog(buffer);
return new BrowserInformationControlInput(previousInput) {
@Override
public String getHtml() {
return buffer.toString();
}
@Override
public Object getInputElement() {
return getHtml();
}
@Override
public String getInputName() {
return "";
}
};
}
return null;
}
/**
* Returns the Javadoc hover style sheet with the current Javadoc font from the preferences.
*
* @return the updated style sheet
* @since 3.4
*/
private static String getStyleSheet() {
if (fgStyleSheet == null) {
try {
final URL url = new URL("platform:/plugin/org.eclipse.ease.ui/resources/EASEHoverStylesheet.css");
final InputStream inputStream = url.openConnection().getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
fgStyleSheet = StringTools.toString(reader);
reader.close();
} catch (final IOException e) {
Logger.error(Activator.PLUGIN_ID, "Cannot read style sheet for hover presentation", e);
}
}
String css = fgStyleSheet;
if (css != null) {
final FontData fontData = JFaceResources.getFontRegistry().getFontData(APPEARANCE_MODULEDOC_FONT)[0];
css = HTMLPrinter.convertTopLevelFont(css, fontData);
}
return css;
}
}