I am dragging and dropping an element from one diagram to another. The drop creates a temporary copy of the element in the target diagram. On event of ‘ExternalObjectsDropped’ a new dialog popup is presented to the user and the user can give a name to the node and either select a ‘create’ button which will create a new node with the chosen name that replaces the temporary copy that was dropped or press ‘cancel’ button that will delete the temporary copy that was dropped.
My issue is with undoManager monitoring these changes. If the user selects ‘cancel,’ currantly I have a transaction of ‘External Copy’ in the history of the undoManager that when I try to undo or redo this transaction if does nothing since it includes in it both the addition and removal of the temporary node.
I want to know if there is a way to remove only this transaction or maybe some other workaround we can think of to avoid having an ‘empty’ transaction in the undoManager.
OK, I’m assuming that all of your code in handling the dialog is happening long after the “ExternalObjectsDropped” DiagramEvent listener has finished executing. In other words, after the drag-and-drop transaction has completed.
And I assume that the user cannot perform any other modifications of the diagram while the dialog is open.
So if the user tells you to add this extra node or whatever you want to do, before you start that transaction, remember whatever was added by the drop. Then perform an undo to delete the dropped node(s). Next start your transaction and re-add that dropped node. Then do whatever additional stuff you want to do. Finally commit the transaction.
If the dialog user instead just wants to cancel the whole drag-and-drop, you just need to perform an undo.
My problem with preforming an undo if the user wants to cancel is that then the user can preform redo on this action and I get this weird situation where the user can redo an action that was canceled.
Also, since this transaction that we undid was just adding a temporary item to the diagram, if the user performs redo (after undoing the transaction in a case of cancel), this temporary item will show in the diagram.
After the undo, call UndoManager.discardHistoryAfterIndex.
This is a partial solution because if the user undid a few transactions and then dragged the element and canceled, he will not be able to redo the transactions he undid because discardHistoryAfterIndex will cause canRedo() to be false.
If the user had performed several undo’s, the drag-and-drop would cause all possible redo’s after that point in the history to be lost/forgotten. So whether the dialog cancels or not does not matter – the state has already been lost.