4. ReportDesigner Undo

The class org.pentaho.reportdesigner.lib.client.undo.Undo is used to collect changes of the report model on an undo stack and is used to undo/redo the changes on the stack.
The main-method of the Undo class contains some sample code.

The commands UndoCommand and RedoCommand are used to revert/redo changes.

The undo contains the changes as a linked list of UndoEntry objects.
An UndoListener can be added to listen for changes.

UndoEntries are usually created as anonymous inner classes.

public void setBackground(@Nullable final Color background)
{
    final Color oldBackground = this.background;
    this.background = background;

    Undo undo = getUndo();
    if (undo != null && !undo.isInProgress())
    {
        undo.startTransaction(PropertyKeys.BACKGROUND);
        undo.add(new UndoEntry()
        {
            public void undo()
            {
                setBackground(oldBackground);
            }


            public void redo()
            {
                setBackground(background);
            }
        });
        undo.endTransaction();
    }

    firePropertyChange(PropertyKeys.BACKGROUND, oldBackground, background);
}

No UndoEntry object must be added to the undo stack when an undo operation is currently in progress.

Transactions can be used to mark a series of UndoEntry objects as one unit of change. E.g changing the background color of multiple selected elements will result in mutliple UndoEntry objects. All UndoEntry objects can be marked as one transaction. Undoing this transaction with the UndoCommand will rollback all background settings.
The first (outermost) started transaction will be used as the main transaction to rollback. Inner/nested transactions have almost no overhead (the transaction name is stored, but that's useful for debugging).

undo.startTransaction(PropertyKeys.BACKGROUND);
element1.setBackground(Color.RED);
element2.setBackground(Color.RED);
element3.setBackground(Color.RED);
undo.endTransaction();

Invoking the undo command will rollback the background color of all three elements at once.

An UndoEntry holds a reference to the element and the value of the operation. A reference to the UndoEntry is held for a long time in the undo stack. Ensure to only add small objects to the undo stack.
Every element containing large cached data should dispose the cached data when the element is removed from the visual report. E.g deleting a StaticImageReportElement disposes the temporary image to prevent OOM exceptions.
The undo stack is currently limited to 10000 UndoEntry objects. The complete oldest transaction is removed as soon as the limit of 10000 UndoEntries is exceeded.

The text/key used in the startTransaction method is currently not used but might be useful to extend the Undo/RedoCommand to show the operation.

The PrintUndoInfosCommand can be used to print the undo stack on the console. The debug menu can be activated by pressing CTRL-ALT-SHIFT-D in the ReportDesigner.