I have the following problem with my EMF based Eclipse application:
Undo works fine. Validation works fine. But when there is a validation error for the data in a GUI field, this blocks the use of the undo action. For example, it is not possible to undo to get back to a valid state for that field.
In this picture it is not possible to use undo:
Tools that are used in the application:
- Eclipse data binding
UpdateValueStrategy
s on the bindings for validation- Undo is implemented using standard
UndoAction
that callsCommandStack.undo
- A
MessageManagerSupport
class that connects the validation framework to the Eclipse Forms based GUI.
The data bindings look like this:
dataBindingContext.bindValue(WidgetProperties.text(...),
EMFEditProperties.value(...), validatingUpdateStrategy, null);
The problem is this:
- The undo system works on the commands that change the model.
- The validation system stops updates from reaching to model when there are validation errors.
To make undos work when there are validation errors I think I could do one of these different things:
- Make undo system work on the GUI layer. (This would be a huge change, it's probably not possible to use EMF for this at all.)
- Make the invalid data in the GUI trigger commands that change the model data, in the same way as valid data does. (This would be okay as long as the data can not be saved to disk. But I can't find a way to do this.)
- Make the validation work directly on the model, maybe triggered by a content listener on the
Resource
. (This is a big change of validation strategy. It doesn't seem possible to track the source GUI control in this stage.)
These solutions either seem impossible or have severe disadvantages.
What is the best way to make undo work even when there are validation errors?
NOTE: I accept Mad Matts answer because their suggestions lead me to my solution. But I'm not really satisfied with that and I wish there was a better one.
If someone at some time finds a better solution I'd be happy to consider to accept it instead of the current one!
It makes sense that the Validator protects your Target value from invalid values. Therefor the target commandstack remains untouched in case of an invalid value. Why would you like to force invalid values being set? Isn't
ctrl + z
in the GUI enough to reset the last valid state?If you still want to set these values to your actual Target model, you can play around with the
UpdateValueStrategy
.I'm not sure where the validation error (
Status.ERROR
) occurs exactly, but you could check where and then force aSetCommand
manually. You can set customIValidator
for each step to yourUpdateValueStrategy
to do that.