# Undo/Redo
# 简介
Foxit PDF SDK for Web 提供了一个名为 "undo-redo" 的插件,它为 PDF 文档添加了撤销和重做功能。用户可以通过 Ctrl+Z 和 Ctrl+Y 组合键来撤销和重做以下操作:
- 添加注释
- 删除注释
- 修改注释
- 等等
此外,该插件还提供了编程接口,允许开发者在自定义应用中实现撤销和重做功能。
# 加载插件
请参考 Addons 简介 一章中的方法。插件加载后, undo-redo 功能便会自动生效, 用户可以通过 Ctrl+Z 和 Ctrl+Y (Mac 中为 Cmd+Z 和 Cmd+Y)来撤销和重做上一步操作。
# 编程接口
除了提供快捷键之外,undo-redo 插件还提供了一系列编程接口方便开发者实现自定义功能。在开始调用接口之前,我们先获取 undo-redo 插件的对象实例:
async function obtainAddonInstanceExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
// 这里就可以开始使用 undoRedoAddon 接口了。
} else {
console.error("UndoRedo Addon instance not found.");
}
}
关于 UndoRedoAddon 详细的接口描述,可以参考 API Reference (opens new window)。
获取到 UndoRedoAddon 实例后,接下来,我们开始使用它吧。
# 1. 撤销操作
undoRedoAddon.undo() 接口用于撤销操作,它可以撤销用户的最后一次操作。请查看例子:
async function undoExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.undo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# 2. 重做操作
undoRedoAddon.redo() 接口用于重做操作需要,它可以重新执行最后一次被撤销的用户操作。请查看例子:
async function redoExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.redo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# 3. 撤销所有操作
UndoRedoAddon.undoAll() 接口用于撤销所有操作,他可以撤销用户所有操作,将文档还原到最初状态。 请查看例子:
async function undoAllExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
undoRedoAddon.undoAll();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
虽然所有操作被撤销,但是依然可以一步一步地重做。
# 4. 记录操作
UndoRedoAddon 还提供了一个 invoke 方法, 通过它,可以传递一个回调函数,该函数接受一个 PDFDoc (opens new window) 对象,这是一个被包装过的对象,它相对于未包装过的 PDFDoc 不同之处在于它可以记录操作,这些被记录的操作可以被撤销和重做。
下面是一个简单的例子,我们在回调函数中记录了创建注释和修改注释的操作。这些操作被记录后,我们还可以通过 undo/redo 接口来撤销和重做:
function wait() {
// 这个函数的作用是让下面的每个步骤执行完后停顿一定时间,方便查看效果。
return new Promise((resolve) => setTimeout(resolve, 2000));
}
async function invokeExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
await undoRedoAddon.invoke(async (pdfDoc) => {
const pdfPage = await pdfDoc.getPageByIndex(0);
const [square, popup] = await pdfPage.addAnnot({
type: "square",
rect: {
left: 0,
right: 100,
bottom: 500,
top: 550,
},
color: 0xff0000, // 初始化外边框颜色为:红色
});
await wait();
// 创建完成后将外边框颜色设置为紫色
await square.setBorderColor(0xff00ff);
});
await wait();
// 撤销后,颜色变回 红色
await undoRedoAddon.undo();
await wait();
// 重做后,颜色变为 紫色
await undoRedoAddon.redo();
await wait();
// 撤销所有,square Annotation 将被删除
await undoRedoAddon.undoAll();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# 支持 Undo/Redo 的 API 列表
下面列举了 Foxit PDF SDK for Web 当前支持撤销和重做操作的 API,
# 1. 支持的对象获取接口
这里列举了一系列接口,这些接口在 UIXAddon.invoke 接口回调函数中调用后会返回一个被包装过的对象。开发者可以调用这个被包装过对象上的方法来记录操作:
- PDFDoc (opens new window) 接口
PDFDoc.getPageByIndex(index): 通过索引获取文档中的页面。PDFDoc.getPageById(id): 通过页面的唯一标识符获取页面。PDFDoc.getAnnots(): 获取文档中的所有注释。
- PDFPage (opens new window) 接口
PDFPage.getAnnots(): 获取页面上的所有注释。PDFPage.getAnnotsByObjectNumArray(objectNums): 通过对象编号数组获取页面上的注释。PDFPage.getAnnotsByIdArray(annotIds): 通过注释标识符数组获取页面上的注释。PDFPage.getMarkupAnnots(): 获取页面上的标记注释。PDFPage.getAnnotTree(): 获取页面上注释的树状结构。
我们举个例子:
async function getAnnotsExample() {
const undoRedoAddon = await pdfui.getAddonInstance("UndoRedoAddon");
if (undoRedoAddon) {
await undoRedoAddon.invoke(async (pdfDoc) => {
const pdfPage = await pdfDoc.getPageByIndex(0);
const [square] = await pdfPage.getAnnotsByObjectNumArray([12002]);
square.setBorderColor(0xFF0000);
});
await undoRedoAddon.undo();
} else {
console.error("UndoRedo Addon instance not found.");
}
}
# 2. 支持的操作接口
这些接口被调用后,其操作将会被自动记录,记录后的操作可以被撤销和重做。要注意的是,这些接口必须在上一段中列举的对象获取接口返回的对象上调用。
- PDFDoc (opens new window) 接口
PDFDoc.addAnnot
- PDFPage (opens new window) 接口
PDFPage.addAnnotPDFPage.removeAnnotByIdPDFPage.removeAnnotByObjectNumber
- Annot (opens new window) 接口(所有注释类的超类):
Annot.setContentAnnot.setRectAnnot.setBorderColorAnnot.setBorderInfoAnnot.setFlags
- Markup (opens new window) 接口(所有Markup注释的超类, 包括: FreeText(callout, textbox, typewriter), ink, line, note, polygon,
polyline,redact,sound,square,stamp, TextMarkup(highlight,squiggly,strikeout,underline) ):
Markup.setOpacityMarkup.setSubjectMarkup.setTitleMarkup.addReplyMarkup.addReviewStateMarkup.addMarkedStateMarkup.setFillColor
- 特定的注释类型:
- Circle (opens new window)
Circle.setMeasureRatioCircle.setMeasureUnitCircle.setMeasureConversionFactorCircle.enableCaptionCircle.setCaptionColor
- Line (opens new window)
Line.setMeasureRatioLine.setMeasureUnitLine.enableCaptionLine.setCaptionColorLine.setEndPointLine.setStartPointLine.setEndingStyleLine.setStyleFillColorLine.setLeaderLineExtendLine.setLeaderLineOffsetLine.setLeaderLineLengthLine.setCaptionOffset
- Polygon (opens new window)
Polygon.enableCaptionPolygon.setCaptionColorPolygon.updateVertexesPolygon.setVertexes
- Polyline (opens new window)
Polyline.setMeasureRatioPolyline.enableCaptionPolyline.setCaptionColorPolyline.setEndingStylePolyline.setStyleFillColorPolyline.updateVertexesPolyline.setVertexes
- Square (opens new window)
Square.setMeasureRatioSquare.setMeasureUnitSquare.setMeasureConversionFactor
- FreeText (opens new window)(typewriter, textbox, callout)
FreeText.setAlignmentFreeText.setInnerRectFreeText.setCalloutLinePointsFreeText.setCalloutLineEndingStyleFreeText.setDefaultAppearanceFreeText.setRotation
- Screen (opens new window)
Screen.setRotation
- Stamp (opens new window)
Stamp.setRotation
- Redact (opens new window)
Redact.setDefaultAppearanceRedact.setOverlayTextRedact.removeOvelayTextRedact.setOverlayTextAlignmentRedact.setRepeatRedact.setAutoFontSizeRedact.setRedactApplyFillColor
- Ink (opens new window)
Ink.setInkList
- Link (opens new window)
Link.setHighlightingModeLink.setAction
- FileAttachment (opens new window)
FileAttachment.setIconName
- Note (opens new window)
Note.setIconName
- Circle (opens new window)