Signature plugin: invisible digital signature

This commit is contained in:
Jakub Melka 2022-05-28 19:42:52 +02:00
parent 3d6954dc41
commit c7e7b76e5b
7 changed files with 497 additions and 120 deletions

View File

@ -4567,6 +4567,37 @@ PDFObjectReference PDFDocumentBuilder::createFormFieldSignature(QString fieldNam
} }
void PDFDocumentBuilder::createInvisibleFormFieldWidget(PDFObjectReference formField,
PDFObjectReference page)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << std::array{ 0.0, 0.0, 0.0, 0.0 };
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Widget");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject widgetObject = objectBuilder.takeObject();
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder << std::array{ formField };
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageObject = objectBuilder.takeObject();
mergeTo(formField, widgetObject);
appendTo(page, pageObject);
}
PDFObjectReference PDFDocumentBuilder::createSignatureDictionary(QByteArray filter, PDFObjectReference PDFDocumentBuilder::createSignatureDictionary(QByteArray filter,
QByteArray subfilter, QByteArray subfilter,
QByteArray contents, QByteArray contents,
@ -4589,7 +4620,7 @@ PDFObjectReference PDFDocumentBuilder::createSignatureDictionary(QByteArray filt
objectBuilder << std::array{ byteRangeItem, byteRangeItem, byteRangeItem, byteRangeItem }; objectBuilder << std::array{ byteRangeItem, byteRangeItem, byteRangeItem, byteRangeItem };
objectBuilder.endDictionaryItem(); objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Contents"); objectBuilder.beginDictionaryItem("Contents");
objectBuilder << contents; objectBuilder << WrapString(contents);
objectBuilder.endDictionaryItem(); objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("M"); objectBuilder.beginDictionaryItem("M");
objectBuilder << signingTime; objectBuilder << signingTime;
@ -5100,14 +5131,6 @@ void PDFDocumentBuilder::setFormFieldValue(PDFObjectReference formField,
} }
void PDFDocumentBuilder::setLanguage(QLocale locale)
{
PDFObjectFactory objectBuilder;
setLanguage(locale.name());
}
void PDFDocumentBuilder::setLanguage(QString language) void PDFDocumentBuilder::setLanguage(QString language)
{ {
PDFObjectFactory objectBuilder; PDFObjectFactory objectBuilder;
@ -5122,6 +5145,14 @@ void PDFDocumentBuilder::setLanguage(QString language)
} }
void PDFDocumentBuilder::setLanguage(QLocale locale)
{
PDFObjectFactory objectBuilder;
setLanguage(locale.name());
}
void PDFDocumentBuilder::setOutline(PDFObjectReference outline) void PDFDocumentBuilder::setOutline(PDFObjectReference outline)
{ {
PDFObjectFactory objectBuilder; PDFObjectFactory objectBuilder;
@ -5256,6 +5287,36 @@ void PDFDocumentBuilder::setPageUserUnit(PDFObjectReference page,
} }
void PDFDocumentBuilder::setSignatureContactInfo(PDFObjectReference signatureDictionary,
QString contactInfoText)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("ContactInfo");
objectBuilder << contactInfoText;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedSignatureDictionary = objectBuilder.takeObject();
mergeTo(signatureDictionary, updatedSignatureDictionary);
}
void PDFDocumentBuilder::setSignatureReason(PDFObjectReference signatureDictionary,
QString reasonText)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Reason");
objectBuilder << reasonText;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedSignatureDictionary = objectBuilder.takeObject();
mergeTo(signatureDictionary, updatedSignatureDictionary);
}
void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount) void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount)
{ {
PDFObjectFactory objectBuilder; PDFObjectFactory objectBuilder;

View File

@ -1235,6 +1235,13 @@ public:
PDFObjectReference signatureValue); PDFObjectReference signatureValue);
///
/// \param formField Form field reference
/// \param page Page reference
void createInvisibleFormFieldWidget(PDFObjectReference formField,
PDFObjectReference page);
/// Creates signature dictionary used for preparation in signing process. Can define parameters of the /// Creates signature dictionary used for preparation in signing process. Can define parameters of the
/// signature. /// signature.
/// \param filter Filter (for example, Adobe.PPKLite, Entrust.PPKEF, CiCi.SignIt, ...) /// \param filter Filter (for example, Adobe.PPKLite, Entrust.PPKEF, CiCi.SignIt, ...)
@ -1450,11 +1457,6 @@ public:
PDFObject value); PDFObject value);
/// Set document language.
/// \param locale Locale, from which is language determined
void setLanguage(QLocale locale);
/// Set document language. /// Set document language.
/// \param language Document language. It should be a language identifier, as defined in ISO 639 /// \param language Document language. It should be a language identifier, as defined in ISO 639
/// and ISO 3166. For example, "en-US", where first two letter means language code (en = /// and ISO 3166. For example, "en-US", where first two letter means language code (en =
@ -1462,6 +1464,11 @@ public:
void setLanguage(QString language); void setLanguage(QString language);
/// Set document language.
/// \param locale Locale, from which is language determined
void setLanguage(QLocale locale);
/// Set document outline. /// Set document outline.
/// \param outline Document outline root /// \param outline Document outline root
void setOutline(PDFObjectReference outline); void setOutline(PDFObjectReference outline);
@ -1527,6 +1534,20 @@ public:
PDFReal unit); PDFReal unit);
/// Sets signature contact info field.
/// \param signatureDictionary Signature dictionary reference
/// \param contactInfoText Contact info text
void setSignatureContactInfo(PDFObjectReference signatureDictionary,
QString contactInfoText);
/// Sets signature reason field.
/// \param signatureDictionary Signature dictionary reference
/// \param reasonText Reason text
void setSignatureReason(PDFObjectReference signatureDictionary,
QString reasonText);
/// This function is used to update trailer dictionary. Must be called each time the final document is /// This function is used to update trailer dictionary. Must be called each time the final document is
/// being built. /// being built.
/// \param objectCount Number of objects (including empty ones) /// \param objectCount Number of objects (including empty ones)

View File

@ -29,6 +29,7 @@
#include <QToolButton> #include <QToolButton>
#include <QMainWindow> #include <QMainWindow>
#include <QMessageBox> #include <QMessageBox>
#include <QFileDialog>
namespace pdfplugin namespace pdfplugin
{ {
@ -334,15 +335,39 @@ void SignaturePlugin::onSignDigitally()
return; return;
} }
QString signatureName = QString("pdf4qt_signature_%1").arg(QString::number(QDateTime::currentMSecsSinceEpoch()));
pdf::PDFInteger offsetMark = 123456789123; pdf::PDFInteger offsetMark = 123456789123;
constexpr const char* offsetMarkString = "123456789123"; constexpr const char* offsetMarkString = "123456789123";
const auto offsetMarkStringLength = std::strlen(offsetMarkString); const auto offsetMarkStringLength = std::strlen(offsetMarkString);
pdf::PDFDocumentBuilder builder(m_document); pdf::PDFDocumentBuilder builder(m_document);
pdf::PDFObjectReference signatureDictionary = builder.createSignatureDictionary("Adobe.PPKLite", "adbe.pkcs7.detached", signature, QDateTime::currentDateTime(), offsetMark); pdf::PDFObjectReference signatureDictionary = builder.createSignatureDictionary("Adobe.PPKLite", "adbe.pkcs7.detached", signature, QDateTime::currentDateTime(), offsetMark);
pdf::PDFObjectReference formField = builder.createFormFieldSignature("signature", { }, signatureDictionary); pdf::PDFObjectReference formField = builder.createFormFieldSignature(signatureName, { }, signatureDictionary);
builder.createAcroForm({ formField }); builder.createAcroForm({ formField });
if (dialog.getSignMethod() == SignDialog::SignDigitallyInvisible)
{
const pdf::PDFCatalog* catalog = m_document->getCatalog();
if (catalog->getPageCount() > 0)
{
const pdf::PDFObjectReference pageReference = catalog->getPage(0)->getPageReference();
builder.createInvisibleFormFieldWidget(formField, pageReference);
}
}
QString reasonText = dialog.getReasonText();
if (!reasonText.isEmpty())
{
builder.setSignatureReason(signatureDictionary, reasonText);
}
QString contactInfoText = dialog.getContactInfoText();
if (!contactInfoText.isEmpty())
{
builder.setSignatureContactInfo(signatureDictionary, contactInfoText);
}
pdf::PDFDocument signedDocument = builder.build(); pdf::PDFDocument signedDocument = builder.build();
// 1) Save the document with incorrect signature // 1) Save the document with incorrect signature
@ -361,8 +386,8 @@ void SignaturePlugin::onSignDigitally()
// 2) Write ranges to be checked // 2) Write ranges to be checked
const pdf::PDFInteger i1 = 0; const pdf::PDFInteger i1 = 0;
const pdf::PDFInteger i2 = indexOfSignature; const pdf::PDFInteger i2 = indexOfSignature - 1;
const pdf::PDFInteger i3 = i2 + signature.size() * 2; const pdf::PDFInteger i3 = i2 + signature.size() * 2 + 2;
const pdf::PDFInteger i4 = buffer.data().size() - i3; const pdf::PDFInteger i4 = buffer.data().size() - i3;
auto writeInt = [&](pdf::PDFInteger offset) auto writeInt = [&](pdf::PDFInteger offset)
@ -393,13 +418,31 @@ void SignaturePlugin::onSignDigitally()
return; return;
} }
buffer.seek(i2); buffer.seek(i2 + 1);
buffer.write(signature.toHex()); buffer.write(signature.toHex());
buffer.close(); buffer.close();
QString fileName = QFileDialog::getSaveFileName(m_dataExchangeInterface->getMainWindow(), tr("Save Signed Document"), getSignedFileName(), tr("Portable Document (*.pdf);;All files (*.*)"));
if (!fileName.isEmpty())
{
QFile signedFile(fileName);
if (signedFile.open(QFile::WriteOnly | QFile::Truncate))
{
signedFile.write(buffer.data());
signedFile.close();
}
}
} }
} }
QString SignaturePlugin::getSignedFileName() const
{
QFileInfo fileInfo(m_dataExchangeInterface->getOriginalFileName());
return fileInfo.path() + "/" + fileInfo.baseName() + "_SIGNED.pdf";
}
void SignaturePlugin::onOpenCertificatesManager() void SignaturePlugin::onOpenCertificatesManager()
{ {
CertificateManagerDialog dialog(m_dataExchangeInterface->getMainWindow()); CertificateManagerDialog dialog(m_dataExchangeInterface->getMainWindow());

View File

@ -112,6 +112,8 @@ private:
void updateGraphics(); void updateGraphics();
void updateDockWidget(); void updateDockWidget();
QString getSignedFileName() const;
std::array<QAction*, LastAction> m_actions; std::array<QAction*, LastAction> m_actions;
std::array<pdf::PDFWidgetTool*, LastTool> m_tools; std::array<pdf::PDFWidgetTool*, LastTool> m_tools;
pdf::PDFPageContentEditorWidget* m_editorWidget; pdf::PDFPageContentEditorWidget* m_editorWidget;

View File

@ -68,6 +68,16 @@ QString SignDialog::getPassword() const
return ui->certificatePasswordEdit->text(); return ui->certificatePasswordEdit->text();
} }
QString SignDialog::getReasonText() const
{
return ui->reasonEdit->text();
}
QString SignDialog::getContactInfoText() const
{
return ui->contactInfoEdit->text();
}
void SignDialog::accept() void SignDialog::accept()
{ {
// Check certificate // Check certificate

View File

@ -47,6 +47,8 @@ public:
SignMethod getSignMethod() const; SignMethod getSignMethod() const;
QString getCertificatePath() const; QString getCertificatePath() const;
QString getPassword() const; QString getPassword() const;
QString getReasonText() const;
QString getContactInfoText() const;
private: private:
Ui::SignDialog* ui; Ui::SignDialog* ui;

View File

@ -103,7 +103,7 @@
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(getPageTreeRoot(), updatedTreeRoot); <property name="code">appendTo(getPageTreeRoot(), updatedTreeRoot);&#xd;
return pageReference;</property> return pageReference;</property>
</QObject> </QObject>
</property> </property>
@ -182,7 +182,7 @@ return pageReference;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">setCatalogAcroForm(acroForm); <property name="code">setCatalogAcroForm(acroForm);&#xd;
return acroForm;</property> return acroForm;</property>
</QObject> </QObject>
</property> </property>
@ -2386,8 +2386,8 @@ return acroForm;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -2610,8 +2610,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -2785,8 +2785,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationReference); updateAnnotationAppearanceStreams(annotationReference);&#xd;
return annotationReference;</property> return annotationReference;</property>
</QObject> </QObject>
</property> </property>
@ -3067,8 +3067,8 @@ return annotationReference;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -3270,8 +3270,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -3545,8 +3545,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -3749,8 +3749,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -3904,8 +3904,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -4044,8 +4044,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -4269,8 +4269,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -4486,8 +4486,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -4768,8 +4768,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -5120,8 +5120,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -5321,8 +5321,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationReference); updateAnnotationAppearanceStreams(annotationReference);&#xd;
return annotationReference;</property> return annotationReference;</property>
</QObject> </QObject>
</property> </property>
@ -5552,8 +5552,8 @@ return annotationReference;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -5812,8 +5812,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -5951,8 +5951,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">mergeTo(parentAnnotation, upgradedParentAnnotation); <property name="code">mergeTo(parentAnnotation, upgradedParentAnnotation);&#xd;
updateAnnotationAppearanceStreams(popupAnnotation); updateAnnotationAppearanceStreams(popupAnnotation);&#xd;
return popupAnnotation;</property> return popupAnnotation;</property>
</QObject> </QObject>
</property> </property>
@ -6106,8 +6106,8 @@ return popupAnnotation;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -6246,8 +6246,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -6470,8 +6470,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -6625,8 +6625,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -6765,8 +6765,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -6969,8 +6969,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -7158,8 +7158,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -7362,8 +7362,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -7517,8 +7517,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -7657,8 +7657,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -7899,9 +7899,9 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">mergeTo(annotationObject, updateAnnotationPopup); <property name="code">mergeTo(annotationObject, updateAnnotationPopup);&#xd;
appendTo(page, pageAnnots); appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -8055,8 +8055,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -8195,8 +8195,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -8399,8 +8399,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots); <property name="code">appendTo(page, pageAnnots);&#xd;
updateAnnotationAppearanceStreams(annotationObject); updateAnnotationAppearanceStreams(annotationObject);&#xd;
return annotationObject;</property> return annotationObject;</property>
</QObject> </QObject>
</property> </property>
@ -8716,8 +8716,8 @@ return annotationObject;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">mergeTo(rootNodeReference, updatedRootNode); <property name="code">mergeTo(rootNodeReference, updatedRootNode);&#xd;
mergeTo(getCatalogReference(), updatedCatalog); mergeTo(getCatalogReference(), updatedCatalog);&#xd;
return rootNodeReference;</property> return rootNodeReference;</property>
</QObject> </QObject>
</property> </property>
@ -8946,6 +8946,116 @@ return rootNodeReference;</property>
<property name="functionDescription">Creates form field of type signature.</property> <property name="functionDescription">Creates form field of type signature.</property>
<property name="returnType">_PDFObjectReference</property> <property name="returnType">_PDFObjectReference</property>
</QObject> </QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">formField</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Form field reference</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">page</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Page reference</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">P</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">page</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Rect</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">std::array{ 0.0, 0.0, 0.0, 0.0 }</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subtype</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Widget")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Type</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Annot")</property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">widgetObject</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Annots</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">std::array{ formField }</property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">pageObject</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">mergeTo(formField, widgetObject);
appendTo(page, pageObject);</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">createInvisibleFormFieldWidget</property>
<property name="functionDescription"></property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction"> <QObject class="codegen::GeneratedFunction">
<property name="objectName"></property> <property name="objectName"></property>
<property name="items"> <property name="items">
@ -9032,7 +9142,7 @@ return rootNodeReference;</property>
<property name="items"/> <property name="items"/>
<property name="dictionaryItemName">Contents</property> <property name="dictionaryItemName">Contents</property>
<property name="objectType">DictionaryItemSimple</property> <property name="objectType">DictionaryItemSimple</property>
<property name="value">contents</property> <property name="value">WrapString(contents)</property>
</QObject> </QObject>
<QObject class="codegen::GeneratedPDFObject"> <QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property> <property name="objectName"></property>
@ -11030,39 +11140,6 @@ return rootNodeReference;</property>
<property name="functionDescription">Sets form field value. Value must be correct for this form field, no checking is performed. Also, if you use this function, annotation widgets, which are attached to this form field, should also be updated (for example, appearance state and sometimes appearance streams).</property> <property name="functionDescription">Sets form field value. Value must be correct for this form field, no checking is performed. Also, if you use this function, annotation widgets, which are attached to this form field, should also be updated (for example, appearance state and sometimes appearance streams).</property>
<property name="returnType">_void</property> <property name="returnType">_void</property>
</QObject> </QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">locale</property>
<property name="parameterType">_QLocale</property>
<property name="parameterDescription">Locale, from which is language determined</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">setLanguage(locale.name());</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">setLanguage</property>
<property name="functionDescription">Set document language.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction"> <QObject class="codegen::GeneratedFunction">
<property name="objectName"></property> <property name="objectName"></property>
<property name="items"> <property name="items">
@ -11120,6 +11197,39 @@ return rootNodeReference;</property>
<property name="functionDescription">Set document language.</property> <property name="functionDescription">Set document language.</property>
<property name="returnType">_void</property> <property name="returnType">_void</property>
</QObject> </QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">locale</property>
<property name="parameterType">_QLocale</property>
<property name="parameterDescription">Locale, from which is language determined</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">setLanguage(locale.name());</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">setLanguage</property>
<property name="functionDescription">Set document language.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction"> <QObject class="codegen::GeneratedFunction">
<property name="objectName"></property> <property name="objectName"></property>
<property name="items"> <property name="items">
@ -11689,6 +11799,134 @@ return rootNodeReference;</property>
<property name="functionDescription">Sets page's user unit. It specifies user space unit, in multiples of 1 / 72 inch.</property> <property name="functionDescription">Sets page's user unit. It specifies user space unit, in multiples of 1 / 72 inch.</property>
<property name="returnType">_void</property> <property name="returnType">_void</property>
</QObject> </QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">signatureDictionary</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Signature dictionary reference</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">contactInfoText</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Contact info text</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">ContactInfo</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">contactInfoText</property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">updatedSignatureDictionary</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">mergeTo(signatureDictionary, updatedSignatureDictionary);</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">setSignatureContactInfo</property>
<property name="functionDescription">Sets signature contact info field.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">signatureDictionary</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Signature dictionary reference</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">reasonText</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Reason text</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Reason</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">reasonText</property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">updatedSignatureDictionary</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">mergeTo(signatureDictionary, updatedSignatureDictionary);</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">setSignatureReason</property>
<property name="functionDescription">Sets signature reason field.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction"> <QObject class="codegen::GeneratedFunction">
<property name="objectName"></property> <property name="objectName"></property>
<property name="items"> <property name="items">
@ -11769,7 +12007,7 @@ return rootNodeReference;</property>
<property name="actionType">Code</property> <property name="actionType">Code</property>
<property name="variableName"></property> <property name="variableName"></property>
<property name="variableType">_void</property> <property name="variableType">_void</property>
<property name="code">m_storage.updateTrailerDictionary(qMove(trailerDictionary)); <property name="code">m_storage.updateTrailerDictionary(qMove(trailerDictionary));&#xd;
updateDocumentInfo(qMove(updatedInfoDictionary));</property> updateDocumentInfo(qMove(updatedInfoDictionary));</property>
</QObject> </QObject>
</property> </property>