Undo/Redo of Blocks and single values

Oct 11, 2010 at 4:21 PM

Hi,

I have a question about Undo/Redo in follwowing situation.

  1. Let's assume I have a grid showing my dataobjects.
  2. Let's assume user is able to edit some values directly in the grid ("simple" change)
  3. Let's assume there are more complex actions (i.e. DragDrop) which force to do several simple changes internally.

 My problem is now, that If the user wants to undo all the changes, complex actions must be un-done at once.

I thought this could be solved with Undo-Points, but I can't see in the moment how. In my understanding it's not enough to define a setUndoPoint(), I would also need something like EndUndoPoint().

Example given:

//Simple action

person.name = "Tarzan";

//Complex action

person.setUndoPoint("MarriageAndMoving");

person.Address = "London";

person.SecondName = "Lord Greystoke";

person.MarriedTo = jane;

//Here a EndUndoPoint() would be ideal, I think

//another simple change

person.Haircut = "short";

 

The problem is now, I can't undo until "MarriageAndMoving" because this will change "haircut" too. But simple Undo() will not take back complex action at once.

Am I missing something? Or is this kind of undo behaviour not possible at the moment?

Best regards,

KingKnecht

 

 

Coordinator
Oct 25, 2010 at 3:43 PM

Hi,

you can only do undo in reverse direction of the change. You can't undo single actions in the middle of the stack.

Jörg

 

Nov 30, 2010 at 4:30 PM
Edited Nov 30, 2010 at 4:38 PM

Hi Jörg,

after working on another project I'm back and focusing the undo/redo problem again. Maybe my previous examples weren't that good... Okay I try again:

Assume we have simple actions and complex actions on data. Simple means only one value is change i.e. user edits a cell-value in a grid. A complex action consists of many simple actions i.e. user is able to drag&drop a data row from one grid to another and if this happens we have to change a lot of values in our data.

I try to visualize user actions:

  1. simple action1
  2. Complex action1, consists of
    1. simple action2
    2. simple action3
    3. simple action4
  3. simple action 5

Now, assume the user doesn't like what he have done and want's to undo:

  1. User does Undo(), simple action 5 (last one on the stack) is un-done
  2. User does Undo() again, simple action 4 is un-done. This is inconsistence state! Because simple action 4 is part of complex action and must be un-done together with 3 and 2.

Inserting a named Undo-Point, creates another problem. Let's assume we create the named undo point before complex action starts:

  1. simple action1
  2. Insert named Undo point here, Complex action1, consists of
    1. simple action2
    2. simple action3
    3. simple action4
  3. simple action 5

Now, the user does Undo() and we do Undo("NamedUndoPoint") then everything to step 1 is un-done. But user only didn't like last simple action 5.

In my opinion, we would need also a marker for the end of a named undo-point:

  1. simple action1
  2. Insert start named Undo point here, Complex action1, consists of
    1. simple action2
    2. simple action3
    3. simple action4
    Insert end named undo point here
  3. simple action 5

Now, if the user does undo() simple action 5 is removed. If user does undo() again we detect the end of a named undo()-block. Thus we know we have to take back everthing until the start of the named undo point.

I hope this explanation was a little bit clearer.

Kind regards,

 

KingKnecht

 

 

Coordinator
Dec 3, 2010 at 12:32 PM

Hi,

to solve the described issues, create an undo point for every transactional operation. In your sample, make an undo point for step 1, step 2 and step 3 and then undo to the named points.

Hope it helps,

Jörg

Dec 3, 2010 at 6:40 PM

Hi Jörg,

sorry, it's me again....

how can I set a named undo point for a simple operation i.e. if the user is editing a grid cell value (grid is bound via BindingSource directly to DOM)?

This would mean I have to do it in the changed property itself between  onPropertyChanging("...") and onPropertyChanged("...")?

Further this would mean I also need a global accessible stack for all the names of the named undo points.

Do you agree?

KingKnecht

 

 

Dec 7, 2010 at 2:54 PM

Hi Jörg,

after further investigations I arrived the point where I say it is not possible at the moment to undo() a block of actions. I anybody knows how, please let me know. I give up... :-(

I don't  understand how to implement your suggested solution:

"to solve the described issues, create an undo point for every transactional operation. In your sample, make an undo point for step 1, step 2 and step 3 and then undo to the named points."

Building a stack of named undo points and trying  to keep it aquivalent to the real undo stack seems less sensible (or impossible). Further undo/redo would then depend on my grid (cell editing event, to be exact) and not on the DOM itself.

Next problem would be, that we can undo() to a named point but not redo(). This would mean in the example above Simple action 2, 3, 4 would be made by single redos. This would be inconsistent state.

Thanks,

KingKnecht