I think I have solved the problem, but is it correct this way? I worry about that if the DSL is distributed in a Jar the file urls cannot be resolved to an (via html) accessible file.
To follow the Xtext guidelines I created a new IImageProvider and an abstract implementation.
public interface IImageProvider {
public URL getImage(Object object);
}
public class AbstractImageProvider implements IImageProvider {
@Inject
private IImageHelper imageHelper;
@Inject
private AbstractUIPlugin uiPlugin;
private IImageProvider delegate;
protected AbstractImageProvider() {
}
protected AbstractImageProvider(IImageProvider delegate) {
this.delegate = delegate;
}
private String getPathSuffix() {
if (this.imageHelper instanceof PluginImageHelper)
return ((PluginImageHelper) this.imageHelper).getPathSuffix();
else
return "";
}
@Override
public URL getImage(Object element) {
URL image = convertToImage(doGetImage(element));
if (image != null) {
return image;
}
else if (delegate != null) {
image = delegate.getImage(element);
if (image != null) {
return image;
}
}
return getDefaultImage();
}
protected URL convertToImage(Object imageDescription) {
if (imageDescription instanceof URL) {
return (URL) imageDescription;
}
else if (imageDescription instanceof String) {
URL bundleUrl = uiPlugin.getBundle().getEntry(
getPathSuffix() + imageDescription.toString());
URL fileUrl = null;
try {
fileUrl = FileLocator.toFileURL(bundleUrl);
}
catch (IOException e) {
fileUrl = null;
}
return fileUrl;
}
return null;
}
protected Object doGetImage(Object element) {
return null;
}
protected URL getDefaultImage() {
return null;
}
}
For easy use with Xtext I created an IEObjectImageProvider and a declarative implementation:
public interface IEObjectImageProvider extends IImageProvider {
public URL getImage(EObject object);
}
public class DeclarativeImageProvider extends AbstractImageProvider implements
IEObjectImageProvider {
private final PolymorphicDispatcher<URL> imageDispatcher = new PolymorphicDispatcher<URL>("image", 1, 1,
Collections .singletonList(this),
new ErrorHandler<URL>() {
public URL handle(Object[] params, Throwable e) {
return handleImageError(params, e);
}
});
@Override
protected Object doGetImage(Object element) {
Object image = imageDispatcher.invoke(element);
if (image != null) {
return image;
}
return super.doGetImage(element);
}
protected URL handleImageError(Object[] params, Throwable e) {
if (e instanceof NullPointerException || e instanceof NoSuchMethodException) {
return getDefaultImage();
}
return Exceptions.throwUncheckedException(e);
}
@Override
public URL getImage(EObject object) {
return super.getImage(object);
}
}
The implementation looks like this:
public class MyDslImageProvider extends DeclarativeImageProvider {
@Inject
protected SmiDefImageProvider(IImageProvider delegate) {
this.delegate = delegate;
}
public Object image(CheckCondition check) {
return "check.png";
}
public String image(Struct struct) {
return "struct.png";
}
}
// in my UiModule:
public Class<? extends IImageProvider> bindIImageProvider() {
return SmiDefImageProvider.class;
}
public Class<? extends IEObjectImageProvider> bindIEObjectImageProvider() {
return SmiDefImageProvider.class;
}
I modified my labelProvider to this:
public class MyDslLabelProviderBase extends DefaultEObjectLabelProvider {
@Inject
protected IEObjectImageProvider imageProvider;
@Override
public Object image(Object element) {
URL image = imageProvider.getImage(element);
if(image != null) {
return ImageDescriptor.createFromURL(image);
}
return super.image(element);
}
}
And in my IEObjectHoverProvider I can use the image URL in image tags:
public class MyDslEObjectHoverProvider extends DefaultEObjectHoverProvider {
@Inject
private IEObjectImageProvider imageHelper;
@Override
protected String getFirstLine(EObject o) {
String imageName = null;
URL imageUrl = imageHelper.getImage(o);
if(imageUrl != null) {
imageName = imageUrl.toExternalForm();
}
String firstLine = super.getFirstLine(o);
StringBuilder builder = new StringBuilder();
// like in JDT
addImageAndLabel(builder, imageName, 16, 16, 2, 2, firstLine, 20, 2);
return builder.toString();
}
}
Violá, there are images in my hover documentation.
[Updated on: Mon, 08 August 2011 09:36]
Report message to a moderator