Tuesday, August 5, 2008

EditingSupport + TreeViewer

On of the product customizations I work on is changing name of the object at tree. The first idea sounded quit reasonable for me so I've started implementing it as in place editor for tree items. one thing I found interesting was: "Since 3.3, an alternative API is available, see ViewerColumn.setEditingSupport(EditingSupport) for a more flexible way of editing values in a column viewer." so I've decided to get it a chance.

DISCLAIMER: I won't take any responsibility of you implementing editing in viewer this way. In fact I hope some of you will show me the right way.

So I have a tree viewer with "default" column which is a tree.
Each column editor (including TreeViewer has editElement method which can be used for editing n'th column for a given element). But it doesn't work cause you need a cell editor for given column. How this is provided ? Via EdditingSupport.
EditingSupport need to be associated with given column, so we need a column. Ok but column apart of having editing support need to have label provider set up. The label provider it needs is an CellLabelProvider. Oh dear can we then reuse our ILabelProvider, IFontProvider etc.. we had by the moment ? Yes, and no. There is one wrapper label provider WrappedViewerLabelProvider but unfortunately with the package access. So to reuse it in 3.4 you must copy the code.
That's all ?? Almost. If you are ok with the default firing the editor (on left mouse click, for programmatic actions or tab moving) it's all (well you need also some code for keep you column of proper size, but that's detail). I need to have editor fired only on my programmed events. To say how the editor should be fired provide EditorActionStrategy for the view.
So how it look like:

TreeViewerEditor.create(fTreeViewer, new NameEditorActivationStrategy(fTreeViewer), ColumnViewerEditor.DEFAULT);
fLabelProvider = new ExtensionCustomizationLabelProvider(getCustomizationInfo(), toolkit);
column.setLabelProvider(new CustomizationViewerLabelProvider(fLabelProvider));
column.setEditingSupport(new NameEditingSupport(fTreeViewer));

where NameEditorStrategy, ExtensionCustomizationLabelProvider, NameEditingSupport are my custom implementations of objects I've mentioned before.

And as I have said before: I really hope there is an easier way.


Tom said...

You are right if you are using a viewer with no column it doesn't make sense to use a EditingSupport and CellLabelProvider. Leave your old code and only use this line:
TreeViewerEditor.create(fTreeViewer, new NameEditorActivationStrategy(fTreeViewer), ColumnViewerEditor.DEFAULT);
to customize the activation strategy.

Bartek Michalik said...

The problem is I don't have old code, but I'll try to write one ;D

thanks for your hint

Tom said...

But why are you then stating that you want to reuse the ILabelProviders you have already written?

The ColumnLabelProvider implements all I*Label interfaces if you start from scratch this is the one I'd recommend to use.

When it comes to editing support with no-column tables/trees I don't have a good solution and I'm not sure whether it is a good idea to allow setting an EditingSupport onto the control directly though this would be needed to use databinding in a no-column scenario.

Would you mind filing a bug about the missing feature to assign a EditingSupport to no-column table/tree and CC me tom.schindl(a)bestsolution.at?

Bartek Michalik said...

well ok I have ILabelProvider but yes I can change it. although it would be nice to have WrappedViewerLabelProvider with public access :)
using data binding in my scenario is not the best solution ;) on change I add an object rather than change existing one.

Tom said...

I don't think we are going to make the wrapper public because its only purpose is and was to translate the old API into the new calls. If your old LabelProvider works why exchange it.

If you need new functionality like tooltip support subclass ColumnLabelProvider and delegate calls to your existing one. This are only my 2 cents so you could file a bug and see what other committers think about this.

Bartek Michalik said...

the problem is that with existing API I need to provide custom column as well as column label provider.
your idea described at https://bugs.eclipse.org/bugs/show_bug.cgi?id=243273
will work like charm, so I can't wait have this feature request resolved :D

Tom said...

Use reflection to get access until then and your problem is solved already today :-)