Undo and redo

PDFTron supports undo/redo for any manipulation of the document.

Undo/Redo using ToolManager class

For convenience, we have provided a class called UndoRedoManager to facilitate undo/redo. This class is attached by default to the ToolManager class. In other words, if you are using ToolManger you don't need to do anything to make undo/redo work. Just ensure you raise the appropriate events existing in ToolManager when you manipulate the document:

MethodDescription
raiseAnnotationsAddedEvent(Map<Annot,Integer>)Call this function when annotations have been added to the document.
raiseAnnotationsPreModifyEvent(Map<Annot,Integer>)Call this function before annotations in the document are modified.
raiseAnnotationsModifiedEvent(Map<Annot,Integer>)Call this function when annotations in the document have been modified.
raiseAnnotationsPreRemoveEvent(Map<Annot,Integer>)Call this function before annotations are removed from the document.
raiseAnnotationsRemovedEvent(Map<Annot,Integer>)Call this function when annotations have been removed from the document.
raiseAnnotationsRemovedEvent(int)Call this function when all annotations in the specified page have been removed from the document.
raiseAllAnnotationsRemovedEvent()Call this function when all annotations in the document have been removed.
raiseAnnotationActionEvent()Call this function when an action has taken place that changes the document.
raiseBookmarkModified()Call this function when document bookmark has been modified.
raisePagesCropped()Call this function when pages of the document have been cropped.
raisePagesAdded(List<Integer>)Call this function when new pages have been added to the document.
raisePagesDeleted(List<Integer>)Call this function when pages have been deleted from the document.
raisePagesRotated(List<Integer>)Call this function when pages in the document have been rotated.

Undo/Redo operation

To do undo/redo operation simply call

String undoInfo = mToolManager.getUndoRedoManger().undo();

or

String redoInfo = mToolManager.getUndoRedoManger().redo();

The undoInfo/redoInfo contains the information about the action that has been undone/redone; for example, it can be something like this when the undo/redo action is corresponding to annotation addition:

{"Action":"Add Text Box","Annot Info":"{\"Page Numbers\":\"1 \",\"Rects\":\"197 511 307 534 \"}"}

From this you can understand the action was adding a text box in page 1 at the rectangle (197 511 307 534). This information can be used later, for example, in jumping to the last modification which will be explained in the next section.

Jump to Undo/Redo

If you are in the PDF view and like the view to jump to the undo/redo changes you can call

mToolManager.getUndoRedoManger().jumpToUndoRedo(PDFViewCtrl, String, boolean)

This function will show the transition with an animation. The second input argument is the attached information to undo action, and the third argument specifies if the action was undo or redo.

Information about Undo/Redo action

There area several facility functions provided in UndoRedoManger to see the action you can undo/redo, including

MethodDescription
boolean canUndo()determines if there is any action to undo in the stack of undo/redo.
boolean canRedo()determines if there is any action to redo in the stack of undo/redo.
String getNextUndoAction()gets the information attached to the next undo action.
String getNextRedoAction()gets the information attached to the next redo action.

The information attached to the undo/redo action can be used to determine the type of action:

MethodDescription
boolean isAddAnnotationAction(Context, String)checks if the information attached to an undo is related to adding annotations.
boolean isModifyAnnotationAction(Context, String)checks if the information attached to an undo is related to modifying annotations.
boolean isRemoveAnnotationAction(Context, String)checks if the information attached to an undo is related to removing annotations.
boolean isAddPagesAction(Context, String)checks if the information attached to an undo is related to adding pages.
boolean isDeletePagesAction(Context, String)checks if the information attached to an undo is related to deleting pages.
boolean isRotatePagesAction(Context, String)checks if the information attached to an undo is related to rotating pages.
boolean isMovePageAction(Context, String)checks if the information attached to an undo is related to moving a page.
boolean isEditPageAction(Context, String)checks if the information attached to an undo is related to editing (adding, deleting, rotating, moving) pages.

Build your own Undo/Redo Manager

If you don't use ToolManger or you'd like to have your own undo/redo control you can use undo/redo APIs in PDFViewCtrl to achieve this.

Enabling Undo/Redo

You need to enable undo/redo in PDFViewCtrl as the first step:

mPdfViewCtrl.enableUndoRedo();

You can see if the undo/redo is enabled in the PDFViewCtrl using:

boolean isUndoRedoEnabled = mPdfViewCtrl.isUndoRedoEnabled();

Undo/Redo Snapshots

After enabling undo/redo, you should determine the snapshots for undo/redo operations. This is done by calling the following when, or shortly after, a modification on the document occurs:

try {
    mPdfViewCtrl.takeUndoSnapshot(info);
} catch (Exception e) {
    e.printStackTrace();
}

Undo/Redo operation

If you have at least one undo snapshot you can back out the last modification using undo() and get the information you passed through when taking the undo snapshot:

try {
    mPdfViewCtrl.cancelRendering();
    info = mPdfViewCtrl.undo();
} catch (Exception e) {
    e.printStackTrace();
}

Or, if you have any undo in the stack you can redo the last undo by

try {
    mPdfViewCtrl.cancelRendering();
    info = mPdfViewCtrl.redo();
} catch (Exception e) {
    e.printStackTrace();
}