Jeff Mesnil
Weblog · About

An Outliner application based on Eclipse RCP

July 31, 2006

While cleaning up my workpace, I (re) discovered a small application I wrote to familiarize myself with Eclipse editors development.

It is a simple outliner which reads and writes OPML files. Each OPML file is opened in an Eclipse Editor. You can navigate the outliner, indent/outdent the outlines, create new outlines and edit them.
To toggle between the edition and the navigation modes, you can use the ESC key (like in vi).

Eclipse Outliner Screenshot

The code is pre-pre alpha (hence the 0.1.1 version) and a lot of essential features are missing:

  • no copy/paste
  • The OPML parser is home-made and parses only a subset of OPML 2.0 (but at least, I can read some OPML 2.0 examples such as states.opml)
  • I pretty sure that the generated OPML is not valid

The fun part of the application is the OutlinerEditor. Each OutlinerEditor is composed of a TreeViewer which displays the outline. The TreeViewer is not editable but each cell of the tree can be edited in place (a la SWT snippet #111).

I released this project on Google Code's project hosting under the Apache License 2.0 and created a corresponding web site to complement the project home. You can check it out using Subversion but to make it simpler to check out, you can import in your workspace the Outliner Team Project Set (provided you have a Subversion plug-in like Subclipse). I don't plan to work extensively on this application but I thought it could be of some interest for new Eclipse RCP developers.

I developped the application on Mac OS X and had the bad surprise to see that the application is not working properly on Linux because I can't navigate the tree with the arrow keys (see issue #3). It seems to be a "bug" in SWT since I can't navigate with the arrow keys in SWT snippet #111 either. Though I'm not sure this is a SWT bug or a platform specific behavior...

Eclipse's ISetSelectionTarget interface

July 3, 2006

I just found a new Interface in Eclipse which I found quite handy.

Let's say that you have an action which creates a new resource and you want to notify views that they have to show this resource.

The key interface is ISetSelectionTarget. If your views respond to this interface (by implementation or adaptation), they can then receive a selectReveal(ISelection selection) message.

For example, one of my view implements ISetSelectionTarget and defines the method:

public void selectReveal(ISelection selection) {
   StructuredSelection ssel = convertSelection(selection);
   if (!ssel.isEmpty()) {
      viewer.getControl().setRedraw(false);
      viewer.setSelection(ssel, true);
      viewer.getControl().setRedraw(true);
   }
}

How do you send this selectReveal() message from your action?
An example is found in the JDT, in the org.eclipse.ui.wizards.newresource.BasicNewResourceWizard class:

public static void selectAndReveal(IResource resource, IWorkbenchWindow window) {
  // validate the input
  if (window == null || resource == null)
      return;
  IWorkbenchPage page = window.getActivePage();
  if (page == null)
      return;    

  // get all the view and editor parts
  List parts = new ArrayList();
  IWorkbenchPartReference refs[] = page.getViewReferences();
  for (int i = 0; i < refs.length; i++) {
      IWorkbenchPart part = refs[i].getPart(false);
      if (part != null)
          parts.add(part);
  }
  refs = page.getEditorReferences();
  for (int i = 0; i < refs.length; i++) {
      if (refs[i].getPart(false) != null)
          parts.add(refs[i].getPart(false));
  }    

  final ISelection selection = new StructuredSelection(resource);
  Iterator itr = parts.iterator();
  while (itr.hasNext()) {
      IWorkbenchPart part = (IWorkbenchPart) itr.next();    

      // get the part's ISetSelectionTarget implementation
      ISetSelectionTarget target = null;
      if (part instanceof ISetSelectionTarget)
          target = (ISetSelectionTarget) part;
      else
          target = (ISetSelectionTarget) part.getAdapter(ISetSelectionTarget.class);    

      if (target != null) {
          // select and reveal resource
          final ISetSelectionTarget finalTarget = target;
          window.getShell().getDisplay().asyncExec(new Runnable() {
              public void run() {
                  finalTarget.selectReveal(selection);
              }
          });
      }
  }
}

However, your code does not need to be that generic. If you already know which view may be interested to be notified, you can use

IViewPart part = page.findView(viewId):

to retrieve the interested IViewPart and after checking that it will respond to ISetSelectionTarget (either by implementation or adaptation), you can send it a selectReveal() message directly.

Eclipse 3.2 and Welcome page on Ubuntu

July 3, 2006

Eclipse 3.2 is out and it is a great release. :-)

However, the default Welcome page I had on my Ubuntu desktop is quite broken

Broken Welcome Page in Eclipse 3.2

  • it is ugly
  • the links to the workbench are broken (links like http://org.eclipse.ui.intro/showPage?id=overview open in Firefox)
  • when I close it, it asks me to save a file

After a little search on eclipe.org SWT FAQ, it appears that by default, Ubuntu is missing the MOZILLA_FIVE_HOME which is required by SWT to use the web browser internally.

I just added this variable before starting Eclipse:

export MOZILLA_FIVE_HOME=/usr/lib/mozilla-firefox/

and the Welcome page appeared as expected:

Welcome Page in Eclipse 3.2

I really like the new theme (Circles) by the way. )

Pearl Jam

May 6, 2006

Pearl Jam

Great new album from Pearl Jam.
It's been a long wait for this one but it's worth it. If you need to be convinced, a clip of "Life Wasted" can be watched on Amazon.

Enjoy the music and the lyrics!

How to stop SWT Control traversal action

April 18, 2006

Another ah-ha moment with Eclipse...

It is quite simple but I stumble upon it before finding how in Eclipse you can stop the traversal of SWT Control from a TraverseListener implementation.

In your listener, handle the TraverseEvent event and then just

event.doit = false;

and the system will stop traversing the Controls.

Everything is well explained in TraverseEvent javadoc (but I'm guilty of not reading javadoc until I need it...). The explanation is worth a read and shows how powerful traversal can be in eclipse using both TraverseEvent detail and doit fields.

Highlights of Greg Stein's keynote

March 22, 2006

Some highlights from Greg Stein's keynote

The Apache Way

  • Communities first, code second
  • Communities over individuals
  • Apache central to Open Source work but Eclipse is also gravitating to the center
  • The license trend is going to the bottom
 Proprietary
  |
  v
 Restricted
  |
  v
 Copyleft (GPL, EPL)
  |
  v
 Non-copyleft (APL, BSD)   

I found it quite interesting to see how Apache is organized and how Eclipse compares to it.

For now, there is few overlaps between Apache and Eclipse communities but it has already started.
For example, both communities now offer an OSGi implementation:

It it going to be interesting to see where things are going...

Use case for scripting a RCP application

March 22, 2006

I attended the Scripting Eclipse panel which was quite interesting (see Ed's transcript.

Scripting Eclipse means a lot of different things to different people.
My own interest is to provide scripting ability to a RCP application so that its users can customize it for their needs and create their own workflow.

For example, imagine that the RCP application is used to manage remote resources. Each resources can be manage individually through a set of methods.
But what if you want to provide a workflow for advanced operations?

One way to do this is through wizards. But with that solution, users lose control like Joel Spolksy explained in his presentation.
Besides it is very difficult to provide wizards which makes simple things simple and complex things possible. They tend to become uncluttered and undecipherable.

Another way is to provide cheatsheets. However, interaction between the cheatsheets and the user interface remains basic. And users are still not in control: they must follow the steps dictated by the cheatsheets.

Now, imagine that we expose a DOM of the managed resources and we let users script their processes. They are in control and they manage the workflow of their resources. They win because they are in control and we (the RCP developpers) win because we can keep our RCP application simple. We just have to expose the simplest useful DOMs to our users to let them handle themselves their more complex and specific processes.

Console DOM for Eclipse Monkey script

March 21, 2006

I wrote a simple DOM to write message to Eclipse console from a Monkey Script.

I have not yet created an update site for it so you have do download it and install it in your plugins directory manually.
It provides a out variable that you can use to write to a console.

Here is the mandatory "Hello, World" example:

--- Came wiffling through the eclipsey wood ---
/*
 * Menu: Console > Hello
 * Kudos: Jeff Mesnil
 * License: EPL 1.0
 * DOM: http://jmesnil.net/eclipse/updates/net.jmesnil.doms 
 */

function main() {
  out.print("Hello, ").println("World");
 }

--- And burbled as it ran! ---

and its output

Hello, World console screenshot

Hook when hovering on a menu item in Eclipse

March 21, 2006

I'm trying to display a message in Eclipse global status bar when hovering on a menu item.

I had the part to display the message (but I'm pretty sure it's the ugliest way I could have found):

if (window instanceof ApplicationWindow) {
    ApplicationWindow appWindow = (ApplicationWindow)window;
    appWindow.setStatus(message);
}

But I can't find how to run that code when hovering on a menu item. I've got the complete control on the menu and its items creation but I don't see where I can plug my code so that it is executed when hovering on a item of my menu.

The reason I need that code is that I'd like to display a description of a Eclipse Monkey script when hovering on a menu item in the Monkey menu (see bug #132601 for a description of this enhancement).

If anyone has an idea, I'd appreciate.

'Find Missing Headers' Monkey Script

March 20, 2006

Still playing with Eclipse Monkey.

I wrote this simple script based on the org.eclipse.dash.doms resources DOM. It looks for Java files to find the files which are missing copyright headers. In my script it is looking for the Eclipse Foundation copyright (Copyright (c) 2005 Eclipse Foundation).

--- Came wiffling through the eclipsey wood ---
  /*
   * Menu: Find Missing Headers
   * Kudos: Jeff Mesnil
   *  License: EPL 1.0
   * DOM: http://download.eclipse.org/technology/dash/update/org.eclipse.dash.doms
   */
    
  function main() {
    var files = resources.filesMatching(".*\\.java");
    var match;
    for each( file in files ) { 
      file.removeMyTasks(  );
      if (!file.lines[1].string.match(/\* Copyright \(c\) 2005 Eclipse Foundation/)) {
           file.lines[1].addMyTask(file);
      }
    }
      window.getActivePage().showView("org.eclipse.ui.views.TaskList");
  }

--- And burbled as it ran! ---

If I run it on my workspace with the imported org.eclipse.eclipsemonkey plug-in, it shows that one file is missing the copyright header:

Java Files missing copyright headers