/*******************************************************************************
* Copyright (c) 2009, 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.ui.editor.hover;
import java.io.*;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.Platform;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.core.*;
import org.eclipse.dltk.internal.ui.editor.EditorUtility;
import org.eclipse.dltk.ui.PreferenceConstants;
import org.eclipse.dltk.ui.ScriptElementLabels;
import org.eclipse.dltk.ui.viewsupport.BasicElementLabels;
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.*;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.php.core.ast.nodes.*;
import org.eclipse.php.core.compiler.PHPFlags;
import org.eclipse.php.core.compiler.ast.nodes.FullyQualifiedReference;
import org.eclipse.php.internal.core.compiler.ast.parser.ASTUtils;
import org.eclipse.php.internal.core.corext.dom.NodeFinder;
import org.eclipse.php.internal.core.typeinference.PHPModelUtils;
import org.eclipse.php.internal.ui.PHPUiPlugin;
import org.eclipse.php.internal.ui.documentation.PHPDocumentationContentAccess;
import org.eclipse.php.internal.ui.documentation.PHPElementLinks;
import org.eclipse.php.internal.ui.util.Messages;
import org.eclipse.php.internal.ui.util.OpenBrowserUtil;
import org.eclipse.php.internal.ui.util.PHPPluginImages;
import org.eclipse.php.ui.PHPElementLabels;
import org.eclipse.php.ui.editor.SharedASTProvider;
import org.eclipse.php.ui.editor.hover.IHoverMessageDecorator;
import org.eclipse.php.ui.editor.hover.IPHPTextHover;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.osgi.framework.Bundle;
public class PHPDocumentationHover extends AbstractPHPEditorTextHover
implements IPHPTextHover, IInformationProviderExtension2 {
@Override
public IHoverMessageDecorator getMessageDecorator() {
return null;
}
/**
* 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(PHPHoverMessages.JavadocHover_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(Messages.format(PHPHoverMessages.JavadocHover_back_toElement_toolTip,
BasicElementLabels.getJavaElementName(previous.getInputName())));
setEnabled(true);
} else {
setToolTipText(PHPHoverMessages.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;
setText(PHPHoverMessages.JavadocHover_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(Messages.format(PHPHoverMessages.JavadocHover_forward_toElement_toolTip,
BasicElementLabels.getJavaElementName(current.getNext().getInputName())));
setEnabled(true);
} else {
setToolTipText(PHPHoverMessages.JavadocHover_forward_toolTip);
setEnabled(false);
}
}
}
/**
* 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(PHPHoverMessages.JavadocHover_openDeclaration);
PHPPluginImages.setLocalImageDescriptors(this, "goto_input.png"); //$NON-NLS-1$ //TODO:
// better
// images
}
/*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
PHPDocumentationBrowserInformationControlInput infoInput = (PHPDocumentationBrowserInformationControlInput) fInfoControl
.getInput(); // TODO: check cast
fInfoControl.notifyDelayedInputChange(null);
fInfoControl.dispose(); // FIXME: should have protocol to hide,
// rather than dispose
try {
// FIXME: add hover location to editor navigation history?
IEditorPart editor = EditorUtility.openInEditor(infoInput.getElement(), true);
EditorUtility.revealInEditor(editor, infoInput.getElement());
} catch (PartInitException e) {
PHPUiPlugin.log(e);
} catch (ModelException e) {
PHPUiPlugin.log(e);
}
}
}
/**
* Presenter control creator.
*
* @since 3.3
*/
public static final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
/*
* @seeorg.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);
String font = PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT;
BrowserInformationControl iControl = new BrowserInformationControl(parent, font, 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 OpenDeclarationAction openDeclarationAction = new OpenDeclarationAction(iControl);
tbm.add(openDeclarationAction);
// final SimpleSelectionProvider selectionProvider = new
// SimpleSelectionProvider();
// OpenExternalBrowserAction openExternalJavadocAction = new
// OpenExternalBrowserAction(
// parent.getDisplay(), selectionProvider);
// selectionProvider
// .addSelectionChangedListener(openExternalJavadocAction);
// selectionProvider.setSelection(new StructuredSelection());
// tbm.add(openExternalJavadocAction);
IInputChangedListener inputChangeListener = new IInputChangedListener() {
@Override
public void inputChanged(Object newInput) {
backAction.update();
forwardAction.update();
if (newInput == null) {
} else if (newInput instanceof BrowserInformationControlInput) {
BrowserInformationControlInput input = (BrowserInformationControlInput) newInput;
Object inputElement = input.getInputElement();
boolean isJavaElementInput = inputElement instanceof IModelElement;
openDeclarationAction.setEnabled(isJavaElementInput);
}
}
};
iControl.addInputChangeListener(inputChangeListener);
tbm.update(true);
addLinkListener(iControl);
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;
}
/*
* @seeorg.eclipse.jdt.internal.ui.text.java.hover.
* AbstractReusableInformationControlCreator
* #doCreateInformationControl(org.eclipse.swt.widgets.Shell)
*/
@Override
public IInformationControl doCreateInformationControl(Shell parent) {
String tooltipAffordanceString = EditorsUI.getTooltipAffordanceString();
if (BrowserInformationControl.isAvailable(parent)) {
String font = PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT;
BrowserInformationControl iControl = new BrowserInformationControl(parent, font,
tooltipAffordanceString) {
/*
* @see
* org.eclipse.jface.text.IInformationControlExtension5#
* getInformationPresenterControlCreator()
*/
@Override
public IInformationControlCreator getInformationPresenterControlCreator() {
return fInformationPresenterControlCreator;
}
};
addLinkListener(iControl);
return iControl;
} else {
return new DefaultInformationControl(parent, tooltipAffordanceString);
}
}
/*
* @seeorg.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) {
String tooltipAffordanceString = EditorsUI.getTooltipAffordanceString();
((IInformationControlExtension4) control).setStatusText(tooltipAffordanceString);
}
return true;
}
}
private static final long LABEL_FLAGS = ScriptElementLabels.ALL_FULLY_QUALIFIED
| ScriptElementLabels.M_PRE_RETURNTYPE | ScriptElementLabels.M_PARAMETER_TYPES
| ScriptElementLabels.M_PARAMETER_NAMES | ScriptElementLabels.M_PARAMETER_INITIALIZERS
| ScriptElementLabels.M_EXCEPTIONS | ScriptElementLabels.F_PRE_TYPE_SIGNATURE
| ScriptElementLabels.M_PRE_TYPE_PARAMETERS | ScriptElementLabels.T_TYPE_PARAMETERS
| ScriptElementLabels.USE_RESOLVED | ScriptElementLabels.M_APP_RETURNTYPE;
private static final long LOCAL_VARIABLE_FLAGS = LABEL_FLAGS & ~ScriptElementLabels.F_FULLY_QUALIFIED
| ScriptElementLabels.F_POST_QUALIFIED;
/**
* 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;
/*
* @seeorg.eclipse.jface.text.ITextHoverExtension2#
* getInformationPresenterControlCreator()
*
* @since 3.1
*/
@Override
public IInformationControlCreator getInformationPresenterControlCreator() {
if (fPresenterControlCreator == null)
fPresenterControlCreator = new PresenterControlCreator();
return fPresenterControlCreator;
}
/*
* @see ITextHoverExtension#getHoverControlCreator()
*
* @since 3.2
*/
@Override
public IInformationControlCreator getHoverControlCreator() {
if (fHoverControlCreator == null)
fHoverControlCreator = new HoverControlCreator(getInformationPresenterControlCreator());
return fHoverControlCreator;
}
private static void addLinkListener(final BrowserInformationControl control) {
control.addLocationListener(PHPElementLinks.createLocationListener(new PHPElementLinks.ILinkHandler() {
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks
* .ILinkHandler #handleInlineJavadocLink(org.eclipse.jdt.core
* .IModelElement)
*/
@Override
public void handleInlineLink(IModelElement linkTarget) {
PHPDocumentationBrowserInformationControlInput hoverInfo = getHoverInfo(
new IModelElement[] { linkTarget }, null,
(PHPDocumentationBrowserInformationControlInput) 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.
* IModelElement)
*/
@Override
public void handleDeclarationLink(IModelElement linkTarget) {
control.notifyDelayedInputChange(null);
control.dispose(); // FIXME: should have protocol to
// hide, rather than dispose
// try {
// FIXME: add hover location to editor navigation
// history?
// JavaUI.openInEditor(linkTarget);
// } catch (PartInitException e) {
// PHPUiPlugin.log(e);
// } catch (ModelException e) {
// PHPUiPlugin.log(e);
// }
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks
* .ILinkHandler#handleExternalLink(java.net.URL,
* org.eclipse.swt.widgets.Display)
*/
@Override
public boolean handleExternalLink(URL url, Display display) {
control.notifyDelayedInputChange(null);
control.dispose(); // FIXME: should have protocol to
// hide, rather than dispose
// open external links in real browser:
OpenBrowserUtil.open(url, display); // $NON-NLS-1$
return true;
}
@Override
public void handleTextSet() {
}
}));
}
/*
* @see
* org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse
* .jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
*/
@Override
public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
return internalGetHoverInfo(textViewer, hoverRegion);
}
private PHPDocumentationBrowserInformationControlInput internalGetHoverInfo(ITextViewer textViewer,
IRegion hoverRegion) {
IModelElement[] elements = getElementsAt(textViewer, hoverRegion);
if (elements == null || elements.length == 0)
return null;
// filter the same namespace
Set<IModelElement> elementSet = new TreeSet<>(new Comparator<IModelElement>() {
@Override
public int compare(IModelElement o1, IModelElement o2) {
if (o1 instanceof IType && o2 instanceof IType) {
IType type1 = (IType) o1;
IType type2 = (IType) o2;
try {
if (PHPFlags.isNamespace(type1.getFlags()) && PHPFlags.isNamespace(type2.getFlags())
&& type1.getElementName().equals(type2.getElementName())) {
return 0;
}
} catch (ModelException e) {
}
}
return 1;
}
});
List<IModelElement> elementList = new ArrayList<>();
for (int i = 0; i < elements.length; i++) {
if (!elementSet.contains(elements[i])) {
elementSet.add(elements[i]);
elementList.add(elements[i]);
}
}
elements = elementList.toArray(new IModelElement[elementList.size()]);
String constantValue;
if (elements.length == 1 && elements[0].getElementType() == IModelElement.FIELD) {
constantValue = getConstantValue((IField) elements[0], hoverRegion);
if (constantValue != null)
constantValue = HTMLPrinter.convertToHTMLContent(constantValue);
} else {
constantValue = null;
}
return getHoverInfo(elements, constantValue, null);
}
/**
* Computes the hover info.
*
* @param elements
* the resolved elements
* @param constantValue
* a constant value iff result contains exactly 1 constant field,
* 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
*/
private static PHPDocumentationBrowserInformationControlInput getHoverInfo(IModelElement[] elements,
String constantValue, PHPDocumentationBrowserInformationControlInput previousInput) {
StringBuffer buffer = new StringBuffer();
boolean hasContents = false;
IModelElement element = null;
int leadingImageWidth = 20;
for (int i = 0; i < elements.length; i++) {
element = elements[i];
if (element instanceof IMember) {
IMember member = (IMember) element;
HTMLPrinter.addSmallHeader(buffer, getInfoText(member, constantValue, true, i == 0));
Reader reader = null;
try {
reader = getHTMLContent(member);
} catch (ModelException e) {
}
if (reader != null) {
HTMLPrinter.addParagraph(buffer, reader);
}
if (i != elements.length - 1) {
buffer.append("<hr>"); //$NON-NLS-1$
}
hasContents = true;
} else if (element.getElementType() == IModelElement.FIELD) {
HTMLPrinter.addSmallHeader(buffer, getInfoText(element, constantValue, true, i == 0));
hasContents = true;
}
}
if (!hasContents)
return null;
if (buffer.length() > 0) {
HTMLPrinter.insertPageProlog(buffer, 0, getStyleSheet());
HTMLPrinter.addPageEpilog(buffer);
return new PHPDocumentationBrowserInformationControlInput(previousInput, element, buffer.toString(),
leadingImageWidth);
}
return null;
}
private static String getInfoText(IModelElement element, String constantValue, boolean allowImage,
boolean isFirstElement) {
StringBuilder label = getInfoText(element);
if (element.getElementType() == IModelElement.FIELD) {
if (constantValue != null) {
label.append(' ');
label.append('=');
label.append(' ');
label.append(constantValue);
}
}
String imageName = null;
if (allowImage) {
URL imageUrl = PHPUiPlugin.getDefault().getImagesOnFSRegistry().getImageURL(element);
if (imageUrl != null) {
imageName = imageUrl.toExternalForm();
}
}
StringBuilder buf = new StringBuilder();
addImageAndLabel(buf, imageName, 16, 16, 2, 2, label.toString(), 20, 2, isFirstElement);
return buf.toString();
}
/*
* @since 3.4
*/
private static boolean isFinal(IField field) {
try {
return PHPFlags.isFinal(field.getFlags());
} catch (ModelException e) {
PHPUiPlugin.log(e);
return false;
}
}
/**
* Returns the constant value for the given field.
*
* @param field
* the field
* @param hoverRegion
* the hover region
* @return the constant value for the given field or <code>null</code> if
* none
* @since 3.4
*/
private String getConstantValue(IField field, IRegion hoverRegion) {
if (!isFinal(field))
return null;
ISourceModule typeRoot = getEditorInputModelElement();
if (typeRoot == null)
return null;
Object constantValue = null;
if (field != null && field.exists()) {
try {
Program unit = SharedASTProvider.getAST(field.getSourceModule(), SharedASTProvider.WAIT_YES, null);
ASTNode node = unit != null
? NodeFinder.perform(unit, field.getNameRange().getOffset(), field.getNameRange().getLength())
: null;
if (node != null) {
if (node instanceof Identifier && node.getParent() instanceof ConstantDeclaration) {
ConstantDeclaration decl = (ConstantDeclaration) node.getParent();
if (decl.initializers().size() == 1 && decl.initializers().get(0) instanceof Scalar) {
Scalar scalar = (Scalar) decl.initializers().get(0);
constantValue = scalar.getStringValue();
}
} else if (node instanceof Scalar && node.getParent() instanceof FunctionInvocation) {
FunctionInvocation invocation = (FunctionInvocation) node.getParent();
Expression function = invocation.getFunctionName().getName();
String functionName = ""; //$NON-NLS-1$
// for PHP5.3
if (function instanceof NamespaceName) {
// global function
if (((NamespaceName) function).isGlobal()) {
functionName = ((NamespaceName) function).getName();
if (functionName.charAt(0) == '\\') {
functionName = functionName.substring(1);
}
} else {
ModuleDeclaration parsedUnit = SourceParserUtil
.getModuleDeclaration(field.getSourceModule(), null);
org.eclipse.dltk.ast.ASTNode func = ASTUtils.findMinimalNode(parsedUnit,
function.getStart(), function.getEnd());
if (func instanceof FullyQualifiedReference) {
functionName = ((FullyQualifiedReference) func).getFullyQualifiedName();
}
// look for the element in current namespace
if (functionName.indexOf('\\') == -1) {
IType currentNamespace = PHPModelUtils.getCurrentNamespace(field.getSourceModule(),
function.getStart());
String fullyQualifiedFuncName = ""; //$NON-NLS-1$
if (currentNamespace != null) {
fullyQualifiedFuncName = "\\" //$NON-NLS-1$
+ currentNamespace.getElementName() + "\\" + functionName; //$NON-NLS-1$
} else {
fullyQualifiedFuncName = functionName;
}
IMethod[] methods = PHPModelUtils.getFunctions(fullyQualifiedFuncName,
field.getSourceModule(), function.getStart(), null);
if (methods != null && methods.length > 0) {
functionName = fullyQualifiedFuncName;
}
}
}
} else if (function instanceof Identifier) {
functionName = ((Identifier) function).getName();
}
if (functionName.equalsIgnoreCase("define") //$NON-NLS-1$
&& invocation.parameters().size() >= 2
&& invocation.parameters().get(1) instanceof Scalar) {
constantValue = ((Scalar) invocation.parameters().get(1)).getStringValue();
}
}
}
} catch (ModelException e) {
} catch (IOException e) {
}
}
if (constantValue == null)
return null;
if (constantValue instanceof String) {
StringBuilder result = new StringBuilder();
String stringConstant = (String) constantValue;
if (stringConstant.length() > 80) {
result.append(stringConstant.substring(0, 80));
result.append(ScriptElementLabels.ELLIPSIS_STRING);
} else {
result.append(stringConstant);
}
return result.toString();
} else if (constantValue instanceof Integer) {
int intValue = ((Integer) constantValue).intValue();
return formatWithHexValue(constantValue, "0x" + Integer.toHexString(intValue)); //$NON-NLS-1$
} else {
return constantValue.toString();
}
}
/**
* Creates and returns a formatted message for the given constant with its
* hex value.
*
* @param constantValue
* the constant value
* @param hexValue
* the hex value
* @return a formatted string with constant and hex values
* @since 3.4
*/
private static String formatWithHexValue(Object constantValue, String hexValue) {
return Messages.format(PHPHoverMessages.JavadocHover_constantValue_hexValue,
new String[] { constantValue.toString(), hexValue });
}
/**
* Returns the Javadoc hover style sheet with the current Javadoc font from
* the preferences.
*
* @return the updated style sheet
* @since 3.4
*/
protected static String getStyleSheet() {
if (fgStyleSheet == null)
fgStyleSheet = loadStyleSheet();
String css = fgStyleSheet;
if (css != null) {
FontData fontData = JFaceResources.getFontRegistry()
.getFontData(PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT)[0];
css = HTMLPrinter.convertTopLevelFont(css, fontData);
}
return css;
}
/**
* Loads and returns the Javadoc hover style sheet.
*
* @return the style sheet, or <code>null</code> if unable to load
* @since 3.4
*/
private static String loadStyleSheet() {
Bundle bundle = Platform.getBundle(PHPUiPlugin.getPluginId());
URL styleSheetURL = bundle.getEntry("/PHPDocumentationHoverStyleSheet.css"); //$NON-NLS-1$
if (styleSheetURL != null) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(styleSheetURL.openStream()));
StringBuilder buffer = new StringBuilder(1500);
String line = reader.readLine();
while (line != null) {
buffer.append(line);
buffer.append('\n');
line = reader.readLine();
}
return buffer.toString();
} catch (IOException ex) {
PHPUiPlugin.log(ex);
return ""; //$NON-NLS-1$
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
}
return null;
}
public static void addImageAndLabel(StringBuilder buf, String imageName, int imageWidth, int imageHeight,
int imageLeft, int imageTop, String label, int labelLeft, int labelTop) {
addImageAndLabel(buf, imageName, imageWidth, imageHeight, imageLeft, imageTop, label, labelLeft, labelTop,
true);
}
private static void addImageAndLabel(StringBuilder buf, String imageName, int imageWidth, int imageHeight,
int imageLeft, int imageTop, String label, int labelLeft, int labelTop, boolean isFirstElement) {
// workaround to make the window wide enough
label = label + " "; //$NON-NLS-1$
if (imageName != null) {
StringBuilder imageStyle = new StringBuilder("position: absolute; "); //$NON-NLS-1$
imageStyle.append("width: ").append(imageWidth).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
imageStyle.append("height: ").append(imageHeight).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
if (isFirstElement) {
imageStyle.append("top: ").append(imageTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
imageStyle.append("left: ").append(imageLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
} else {
imageStyle.append("margin-top: ").append(imageTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
imageStyle.append("margin-left: ").append(-imageLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
}
buf.append("<!--[if lte IE 6]><![if gte IE 5.5]>\n"); //$NON-NLS-1$
buf.append("<span style=\"").append(imageStyle) //$NON-NLS-1$
.append("filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='").append(imageName) //$NON-NLS-1$
.append("')\"></span>\n"); //$NON-NLS-1$
buf.append("<![endif]><![endif]-->\n"); //$NON-NLS-1$
buf.append("<!--[if !IE]>-->\n"); //$NON-NLS-1$
buf.append("<img style='").append(imageStyle).append("' src='").append(imageName).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
buf.append("<!--<![endif]-->\n"); //$NON-NLS-1$
buf.append("<!--[if gte IE 7]>\n"); //$NON-NLS-1$
buf.append("<img style='").append(imageStyle).append("' src='").append(imageName).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
buf.append("<![endif]-->\n"); //$NON-NLS-1$
}
buf.append("<div style='word-wrap:break-word;"); //$NON-NLS-1$
if (imageName != null) {
buf.append("margin-left: ").append(labelLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("margin-top: ").append(labelTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
}
buf.append("'>"); //$NON-NLS-1$
buf.append(label);
buf.append("</div>"); //$NON-NLS-1$
}
protected static Reader getHTMLContent(IMember curr) throws ModelException {
String html = PHPDocumentationContentAccess.getHTMLContent(curr);
if (html != null) {
return new StringReader(html);
}
return null;
// return ScriptDocumentationAccess.getHTMLContentReader(PHPNature.ID,
// curr, true, true);
}
private static StringBuilder getInfoText(IModelElement member) {
long flags = member.getElementType() == IModelElement.FIELD ? LOCAL_VARIABLE_FLAGS : LABEL_FLAGS;
String label = PHPElementLabels.getDefault().getElementLabel(member, flags);
return new StringBuilder(label);
}
}