Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Images in HoverProvider
Images in HoverProvider [message #713205] Mon, 08 August 2011 08:05 Go to next message
Daniel Missing name is currently offline Daniel Missing nameFriend
Messages: 101
Registered: July 2011
Senior Member
Hi everybody.

I just wanted to enhance the look of my hover documentation by adding images like the JDT hovering does. As the hover documentation is HTML it sounds quite easy to add an image to the getFirstLine() HTML.

I thought it would be great to use the images provided by the ILabelProvider because those are the images used everywhere (outline, content assist,..). Here the problem starts: For embedding images to HTML I need an image URL but the ILabelProvider only provides swt image instances. The JDT also uses URLs but they write all their images into a temporary directory on the filesystem and reference them.

What would be the best way to define all images at central point?

I thought of creating an injected IImageProvider which delivers URLs for the ILabelProvider (use IImageHelper.getImage(ImageDescriptor.createFromURL()) and the IEObjectHoverProvider. But there I only receive a strange bundle-URL which cannot be used in the hovering.

Is there probably a better way to embedd SWT-Image instance into the hovers?

Cheers
Daniel

[Updated on: Mon, 08 August 2011 09:04]

Report message to a moderator

Re: Images in HoverProvider [message #713268 is a reply to message #713205] Mon, 08 August 2011 09:34 Go to previous message
Daniel Missing name is currently offline Daniel Missing nameFriend
Messages: 101
Registered: July 2011
Senior Member
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

Previous Topic:[Question] Xtext 2.0 / Xtend2 Generator Development
Next Topic:Content Assist error
Goto Forum:
  


Current Time: Tue Apr 20 10:30:31 GMT 2021

Powered by FUDForum. Page generated in 0.01345 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top