Some test text!

Discord Logo

Chat with us

PDFTron is now Apryse, learn more here.

Undo / redo edits to a PDF file using C#

More languages

More languages
Java (Android)
C++
C#
C# (.NET Core)
Go
Java
Kotlin
Obj-C
JS (Node.js)
PHP
Python
Ruby
C# (UWP)
VB
C# (Xamarin)

The PDFTron 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 C# code shows how to use PDFTron 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 C# PDF Library.

Get Started Samples Download

To run this sample, get started with a free trial of Apryse SDK.

//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.     
//---------------------------------------------------------------------------------------

using System;
using pdftron;
using pdftron.Common;
using pdftron.PDF;
using pdftron.SDF;

using NUnit.Framework;

namespace MiscellaneousSamples
{
	/// <summary>
	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to use the UndoRedo API.
	//---------------------------------------------------------------------------------------
	/// </summary>
	[TestFixture]
	public class UndoRedoTest
	{
		
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[Test]
		public static void Sample()
		{
			// The first step in every application using PDFNet is to initialize the 
			// library and set the path to common PDF resources. The library is usually 
			// initialized only once, but calling Initialize() multiple times is also fine.

			// Relative path to the folder containing test files.
			const string input_path =  "TestFiles/";

			try  
			{
				// Open the PDF document.
                using (PDFDoc doc = new PDFDoc(Utils.GetAssetTempFile(input_path + "newsletter.pdf")))
                using (ElementBuilder bld = new ElementBuilder())	// Used to build new Element objects
                using (ElementWriter writer = new ElementWriter())	// Used to write Elements to the page	
                {
                    UndoManager undo_manager = doc.GetUndoManager();

					// Take a snapshot to which we can undo after making changes.
                    ResultSnapshot snap0 = undo_manager.TakeSnapshot();

                    DocSnapshot snap0_state = snap0.CurrentState();

                    Page page = doc.PageCreate();	// Start a new page

                        writer.Begin(page);		// Begin writing to this page

                    // ----------------------------------------------------------
                    // Add JPEG image to the file
                    Image img = Image.Create(doc, Utils.GetAssetTempFile(input_path + "peppers.jpg"));
                    Element element = bld.CreateImage(img, new Matrix2D(200, 0, 0, 250, 50, 500));
                    writer.WritePlacedElement(element);

                    writer.End();	// Finish writing to the page
                    doc.PagePushFront(page);

					// Take a snapshot after making changes, so that we can redo later (after undoing first).
                    ResultSnapshot snap1 = undo_manager.TakeSnapshot();

                    if (snap1.PreviousState().Equals(snap0_state))
                    {
                        Console.WriteLine("snap1 previous state equals snap0_state; previous state is correct");
                    }

                    DocSnapshot snap1_state = snap1.CurrentState();

                    doc.Save(Utils.CreateExternalFile("addimage.pdf"), SDFDoc.SaveOptions.e_incremental);

					if (undo_manager.CanUndo())
					{
						ResultSnapshot undo_snap = undo_manager.Undo();

						doc.Save(Utils.CreateExternalFile("addimage_undone.pdf"), SDFDoc.SaveOptions.e_incremental);

						DocSnapshot undo_snap_state = undo_snap.CurrentState();

						if (undo_snap_state.Equals(snap0_state))
						{
							Console.WriteLine("undo_snap_state equals snap0_state; undo was successful");
						}

						if (undo_manager.CanRedo())
						{
							ResultSnapshot redo_snap = undo_manager.Redo();
							
							doc.Save(Utils.CreateExternalFile("addimage_redone.pdf"), SDFDoc.SaveOptions.e_incremental);

							if (redo_snap.PreviousState().Equals(undo_snap_state))
							{
								Console.WriteLine("redo_snap previous state equals undo_snap_state; previous state is correct");
							}

							DocSnapshot redo_snap_state = redo_snap.CurrentState();

							if (redo_snap_state.Equals(snap1_state))
							{
								Console.WriteLine("Snap1 and redo_snap are equal; redo was successful");
							}
						}
						else
						{
							Console.WriteLine("Problem encountered - cannot redo.");
						}
					}
					else
					{
						Console.WriteLine("Problem encountered - cannot undo.");
					}
                }
			}
			catch (PDFNetException e) 
			{
				Console.WriteLine(e.Message);
				Assert.True(false);
			}
		}
    }
}