Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 213623

Summary: DataBinding ViewersObservables should expose widget
Product: [Eclipse Project] Platform Reporter: Thomas Kratz <eiswind>
Component: UIAssignee: Boris Bokowski <bokowski>
Status: VERIFIED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: adietish, eclipse, tom.schindl
Version: 3.3.1Keywords: helpwanted
Target Milestone: 3.4 M5   
Hardware: PC   
OS: Windows Vista   
Whiteboard:
Attachments:
Description Flags
IViewerObservableValue/List
none
Adapts ValidationStatusMap for IMessageManagers none

Description Thomas Kratz CLA 2007-12-20 13:49:49 EST
HI there, I made some steps into using the validation of the databinding framework today. It looks promising to me. But I came across the following problem:

I use the messageManager of ManagedForm for my validation messages up to now. It has the nice feature that it searches for the Label of a widget and displays it magically in the validation messages. So I thought no problem, I could have a custom IStatus and pass the widget to the message manager.

That is fine with the SWTObservables but when it comes to Viewers I dig in the dirt as there is no way for me to get hold on the viewers widget. So I thought it would come handy if the ViewersObservables implemented SWTObservable, wouldnt be to hard to do that.

What do you you think about that ? The problem is that ISelectionProvider hides the widget, so there would be some ugly code.
Comment 1 Boris Bokowski CLA 2007-12-20 14:07:04 EST
This sounds very useful. Would you be willing to contribute some of your code to the data binding framework? I am not sure in which plug-in it should be, but we can figure that out later.

As for getting back a viewer from an observable, I would suggest adding

public interface IViewerObservable {
  public Viewer getViewer();
}
public interface IViewerObservableValue extends IObservableValue,
  IViewerObservable {
}
public interface IViewerObservableList extends IObservableList,
  IViewerObservable {
}

and then adding methods in ViewersObservables:

public static IViewerObservableValue observeSingleSelection(Viewer viewer) {
 ... 
}
public static IViewerObservableList observeMultiSelection(Viewer viewer) {
 ...
}

I'm not sure whether this could lead to ambiguities when calling these methods; if it does, we should pick different names to avoid that clients have to put explicit casts in their code.
Comment 2 Thomas Kratz CLA 2007-12-20 14:27:51 EST
surely I can do that. But it wont be too nice. the ViewersObservables take ISelectionProviders which can be many things.. I am not too deep into which JFace viewers exist today as I come along with combos and tables in my app. Can you point me out which viewers we need to cover ?

I also will build a custom BindingContext which will take up a MessageManager from the Form to show the messages ( I use the Context as I build "magic" validators in createUpdateStrategy..., I have all the validation info annotated (hibernate...) on my model objects, so I can build the validation from that. Thats very specific, but maybe someone can use the bridge to the messagemanager.
Comment 3 Thomas Kratz CLA 2007-12-20 14:36:38 EST
Should we expose a StructuredViewer ? What to do if the ISelectionProvider is not a StructuredViewer ? (guess this is not intented to be so, but who knows ?)
Comment 4 Boris Bokowski CLA 2007-12-20 15:04:04 EST
(In reply to comment #2)
> the ViewersObservables take
> ISelectionProviders which can be many things..

I don't understand - did you notice that Viewer (indirectly) implements ISelectionProvider? Viewer is the abstract superclass of TableViewer, TreeViewer, ComboViewer, etc.

We need to ensure binary compatibility, so we cannot take methods away. Adding two new methods on ViewersObservables is the best we can do.

As for introducing IViewerObservable instead of using ISWTObservable: Once you have a viewer and you need access to the underlying SWT control, you can call Viewer.getControl().
Comment 5 Thomas Kratz CLA 2007-12-20 15:17:52 EST
Created attachment 85682 [details]
IViewerObservableValue/List
Comment 6 Thomas Kratz CLA 2007-12-20 15:20:06 EST
Please have a look at it. Provided simple tests.
ViewersObservables is restricted to Viewer now, so everything should be fine. One could add a ViewPart or sth as selection provider that was what I was thinking about. Please let me know if/when you integrate it in the codebase. Thx.
Comment 7 Boris Bokowski CLA 2007-12-20 15:47:34 EST
Thanks for the contribution. I would like to have dedicated subclasses that never return null from getViewer(). I'll add that before I release the patch. Feel free to update the patch if you have time.

Any chance that you can extract reusable code that connects data binding validation results to the UI Forms MessageManager, and contribute that too? ;)
Comment 8 Thomas Kratz CLA 2007-12-20 15:54:44 EST
If you build subclasses will the old ViewerObservables methods return the new subclasses then ? I ask because I use generated code from swt designer for my gui and that uses the old methods naturally. if i could cast to IViewerObservableValue would be great.

Ill have a look what I can do about the message manager. I want it anyway :)
Comment 9 Boris Bokowski CLA 2007-12-20 16:22:43 EST
We could have an instanceof check in ViewersObservables that uses the subclass if the selection provider is a viewer.

I just want to make sure that clients can do something like this:

if (observable instanceof IViewerObservable) {
  Viewer viewer = ((IViewerObservable)observable).getViewer();
}

without having to also check for a null return value from getViewer().
Comment 10 Thomas Kratz CLA 2007-12-20 16:30:08 EST
That sounds great. Sorry if Im still not too deep into binding, but will the validationStatusMap fire a change event if a single status changes ? then I could hook up into that and it wont be too complicated to get the MessageManager up to it.
Comment 11 Boris Bokowski CLA 2007-12-20 20:30:01 EST
(In reply to comment #10)
> will the
> validationStatusMap fire a change event if a single status changes ?

It should - if not, it's a bug.
Comment 12 Thomas Kratz CLA 2007-12-21 03:50:03 EST
Ok ok I dumb. I attached my solution. One can easily usei it by
m_bindingContext.getValidationStatusMap().addMapChangeListener(
				new MessageManagerListener(managedForm.getMessageManager()));
				
It should work right off. If you find it nice your free to integrate it.
Comment 13 Thomas Kratz CLA 2007-12-21 03:51:07 EST
Created attachment 85704 [details]
Adapts ValidationStatusMap for IMessageManagers
Comment 14 Boris Bokowski CLA 2008-02-03 23:38:02 EST
Fix released to HEAD. I ended up writing the whole thing from scratch - I used Mylyn to look at the bug and didn't realize I already had a patch attached to this bug.

About the interface to IMessageManager: I am not sure what to do with that since it depends on ui.forms. Because of this, we cannot put it in org.eclipse.jface.databinding, not even in org.eclipse.ui.workbench. We could try to get it into org.eclipse.ui.forms - how about you file a bug (Platform UA, prefix with [Forms]) and cc me?
Comment 15 Boris Bokowski CLA 2008-02-05 14:09:56 EST
Verified by code inspection on Windows XP using I20080205-0010.
Comment 16 Peter Centgraf CLA 2008-02-20 16:17:51 EST
How would this behave if the data binding context is disposed and recreated while the widgets are still in use?  I do this regularly, since the model side of the binding is replaced whenever a remote operation occurs in our 3-tier RCP app.  A casual review of this code makes me think that it would cause ugly visual artifacts, since the MessageManager redraws the Form for each change to the messages.  Users would see the number of messages count down rapidly and then count back up again.

My solution is to attach a custom ValidationMarker class to each SWT widget via setData().  This class performs the same bridging role as the code attached here, but it acts per widget and provides stability across re-binding.  Additionally, I setRedraw(false) for the entire form during re-binding for extra safety.
Comment 17 Boris Bokowski CLA 2008-02-20 16:49:59 EST
(In reply to comment #16)
> How would this behave if the data binding context is disposed and recreated
> while the widgets are still in use?

Hi Peter, thanks for your comments - would you mind copying it over to bug 219661 (which I should have linked to from here but forgot) - thanks!
Comment 18 Kim Horne CLA 2008-04-25 14:45:37 EDT
Boris: does this need the contributed keyword?
Comment 19 Boris Bokowski CLA 2008-04-25 18:11:53 EDT
(In reply to comment #18)
> Boris: does this need the contributed keyword?
> 

no - see comment 14