The Apryse SDK has a low-level facility for undo and redo operations. It is a API that applies to any edits made to a particular document (not just annotations). This sample Java code shows how to use Apryse SDK to walk back and forth on a fully general, bit-exact list of document states. Saving changes in a mode that is not 'incremental' will wipe out the undo-redo state list; the API will not be able to access old snapshots anymore. See the undoing and redoing guide for more information. Learn more about our Android SDK.
1package com.pdftron.android.pdfnetsdksamples.samples;//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import com.pdftron.android.pdfnetsdksamples.OutputListener;
7import com.pdftron.android.pdfnetsdksamples.PDFNetSample;
8import com.pdftron.android.pdfnetsdksamples.R;
9import com.pdftron.android.pdfnetsdksamples.util.Utils;
10import com.pdftron.common.Matrix2D;
11import com.pdftron.pdf.Element;
12import com.pdftron.pdf.ElementBuilder;
13import com.pdftron.pdf.ElementWriter;
14import com.pdftron.pdf.Image;
15import com.pdftron.pdf.PDFDoc;
16import com.pdftron.pdf.Page;
17import com.pdftron.sdf.DocSnapshot;
18import com.pdftron.sdf.ResultSnapshot;
19import com.pdftron.sdf.SDFDoc;
20import com.pdftron.sdf.UndoManager;
21
22import java.util.ArrayList;
23
24//---------------------------------------------------------------------------------------
25// The following sample illustrates how to use the UndoRedo API.
26//---------------------------------------------------------------------------------------
27public class UndoRedoTest extends PDFNetSample {
28
29	private static OutputListener mOutputListener;
30
31	private static ArrayList<String> mFileList = new ArrayList<>();
32
33    public UndoRedoTest() {
34        setTitle(R.string.sample_undoredo_title);
35        setDescription(R.string.sample_undoredo_description);
36    }
37
38	@Override
39	public void run(OutputListener outputListener) {
40		super.run(outputListener);
41		mOutputListener = outputListener;
42		mFileList.clear();
43		printHeader(outputListener);
44		try 
45		{
46			// The first step in every application using PDFNet is to initialize the
47			// library and set the path to common PDF resources. The library is usually
48			// initialized only once, but calling Initialize() multiple times is also fine.
49
50			// Open the PDF document.
51			try (PDFDoc doc = new PDFDoc(Utils.getAssetTempFile(INPUT_PATH + "newsletter.pdf").getAbsolutePath())) {
52
53				UndoManager undo_manager = doc.getUndoManager();
54
55				// Take a snapshot to which we can undo after making changes.
56				ResultSnapshot snap0 = undo_manager.takeSnapshot();
57
58				DocSnapshot snap0_state = snap0.currentState();
59				
60				Page page = doc.pageCreate();	// Start a new page
61
62				ElementBuilder bld = new ElementBuilder();		// Used to build new Element objects
63				ElementWriter writer = new ElementWriter();		// Used to write Elements to the page	
64				writer.begin(page);		// Begin writing to this page
65
66				// ----------------------------------------------------------
67				// Add JPEG image to the file
68				Image img = Image.create(doc, Utils.getAssetTempFile(INPUT_PATH + "peppers.jpg").getAbsolutePath());
69				Element element = bld.createImage(img, new Matrix2D(200, 0, 0, 250, 50, 500));
70				writer.writePlacedElement(element);
71
72				writer.end();	// Finish writing to the page
73				doc.pagePushFront(page);
74
75				// Take a snapshot after making changes, so that we can redo later (after undoing first).
76				ResultSnapshot snap1 = undo_manager.takeSnapshot();
77
78				if (snap1.previousState().equals(snap0_state))
79				{
80					mOutputListener.println("snap1 previous state equals snap0_state; previous state is correct");
81				}
82				
83				DocSnapshot snap1_state = snap1.currentState();
84
85				doc.save(Utils.createExternalFile("addimage.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.INCREMENTAL, null);
86
87				if (undo_manager.canUndo())
88				{
89					ResultSnapshot undo_snap;
90					undo_snap = undo_manager.undo();
91
92					doc.save(Utils.createExternalFile("addimage_undone.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.INCREMENTAL, null);
93
94					DocSnapshot undo_snap_state = undo_snap.currentState();
95
96					if (undo_snap_state.equals(snap0_state))
97					{
98						mOutputListener.println("undo_snap_state equals snap0_state; undo was successful");
99					}
100					
101					if (undo_manager.canRedo())
102					{
103						ResultSnapshot redo_snap = undo_manager.redo();
104
105						doc.save(Utils.createExternalFile("addimage_redone.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.INCREMENTAL, null);
106
107						if (redo_snap.previousState().equals(undo_snap_state))
108						{
109							mOutputListener.println("redo_snap previous state equals undo_snap_state; previous state is correct");
110						}
111						
112						DocSnapshot redo_snap_state = redo_snap.currentState();
113						
114						if (redo_snap_state.equals(snap1_state))
115						{
116							mOutputListener.println("Snap1 and redo_snap are equal; redo was successful");
117						}
118					}
119					else
120					{
121						mOutputListener.println("Problem encountered - cannot redo.");
122					}
123				}
124				else
125				{
126					mOutputListener.println("Problem encountered - cannot undo.");
127				}
128			}
129
130			// Calling Terminate when PDFNet is no longer in use is a good practice, but
131			// is not required.
132		}
133		catch (Exception e) 
134		{
135			mOutputListener.printError(e.getStackTrace());
136		}
137
138		for (String file : mFileList) {
139			addToFileList(file);
140		}
141		printFooter(outputListener);
142	}
143
144}
1package com.pdftron.android.pdfnetsdksamples.samples
2
3//---------------------------------------------------------------------------------------
4// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
5// Consult legal.txt regarding legal and license information.
6//---------------------------------------------------------------------------------------
7
8import com.pdftron.android.pdfnetsdksamples.OutputListener
9import com.pdftron.android.pdfnetsdksamples.PDFNetSample
10import com.pdftron.android.pdfnetsdksamples.R
11import com.pdftron.android.pdfnetsdksamples.util.Utils
12import com.pdftron.common.Matrix2D
13import com.pdftron.pdf.ElementBuilder
14import com.pdftron.pdf.ElementWriter
15import com.pdftron.pdf.Image
16import com.pdftron.pdf.PDFDoc
17import com.pdftron.sdf.ResultSnapshot
18import com.pdftron.sdf.SDFDoc
19import java.util.*
20
21//---------------------------------------------------------------------------------------
22// The following sample illustrates how to use the UndoRedo API.
23//---------------------------------------------------------------------------------------
24class UndoRedoTest : PDFNetSample() {
25    init {
26        setTitle(R.string.sample_undoredo_title)
27        setDescription(R.string.sample_undoredo_description)
28    }
29
30    override fun run(outputListener: OutputListener?) {
31        super.run(outputListener)
32        mOutputListener = outputListener
33        mFileList.clear()
34        printHeader(outputListener!!)
35        try {
36            // The first step in every application using PDFNet is to initialize the
37            // library and set the path to common PDF resources. The library is usually
38            // initialized only once, but calling Initialize() multiple times is also fine.
39
40            // Open the PDF document.
41            PDFDoc(Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "newsletter.pdf")!!.absolutePath).use { doc ->
42                val undo_manager = doc.undoManager
43
44                // Take a snapshot to which we can undo after making changes.
45                val snap0 = undo_manager.takeSnapshot()
46
47                val snap0_state = snap0.currentState()
48
49                val page = doc.pageCreate()    // Start a new page
50
51                val bld = ElementBuilder()        // Used to build new Element objects
52                val writer = ElementWriter()        // Used to write Elements to the page
53                writer.begin(page)        // Begin writing to this page
54
55                // ----------------------------------------------------------
56                // Add JPEG image to the file
57                val img = Image.create(doc, Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "peppers.jpg")!!.absolutePath)
58                val element = bld.createImage(img, Matrix2D(200.0, 0.0, 0.0, 250.0, 50.0, 500.0))
59                writer.writePlacedElement(element)
60
61                writer.end()    // Finish writing to the page
62                doc.pagePushFront(page)
63
64                // Take a snapshot after making changes, so that we can redo later (after undoing first).
65                val snap1 = undo_manager.takeSnapshot()
66
67                if (snap1.previousState().equals(snap0_state)) {
68                    mOutputListener!!.println("snap1 previous state equals snap0_state; previous state is correct")
69                }
70
71                val snap1_state = snap1.currentState()
72
73                doc.save(Utils.createExternalFile("addimage.pdf", mFileList).absolutePath, SDFDoc.SaveMode.INCREMENTAL, null)
74
75                if (undo_manager.canUndo()) {
76                    val undo_snap: ResultSnapshot
77                    undo_snap = undo_manager.undo()
78
79                    doc.save(Utils.createExternalFile("addimage_undone.pdf", mFileList).absolutePath, SDFDoc.SaveMode.INCREMENTAL, null)
80
81                    val undo_snap_state = undo_snap.currentState()
82
83                    if (undo_snap_state.equals(snap0_state)) {
84                        mOutputListener!!.println("undo_snap_state equals snap0_state; undo was successful")
85                    }
86
87                    if (undo_manager.canRedo()) {
88                        val redo_snap = undo_manager.redo()
89
90                        doc.save(Utils.createExternalFile("addimage_redone.pdf", mFileList).absolutePath, SDFDoc.SaveMode.INCREMENTAL, null)
91
92                        if (redo_snap.previousState().equals(undo_snap_state)) {
93                            mOutputListener!!.println("redo_snap previous state equals undo_snap_state; previous state is correct")
94                        }
95
96                        val redo_snap_state = redo_snap.currentState()
97
98                        if (redo_snap_state.equals(snap1_state)) {
99                            mOutputListener!!.println("Snap1 and redo_snap are equal; redo was successful")
100                        }
101                    } else {
102                        mOutputListener!!.println("Problem encountered - cannot redo.")
103                    }
104                } else {
105                    mOutputListener!!.println("Problem encountered - cannot undo.")
106                }
107                // Calling Terminate when PDFNet is no longer in use is a good practice, but
108                // is not required.
109            }
110        } catch (e: Exception) {
111            mOutputListener!!.printError(e.stackTrace)
112        }
113
114        for (file in mFileList) {
115            addToFileList(file)
116        }
117        printFooter(outputListener)
118    }
119
120    companion object {
121
122        private var mOutputListener: OutputListener? = null
123
124        private val mFileList = ArrayList<String>()
125    }
126
127}
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales