File attachment annotation graphics

This commit is contained in:
Jakub Melka 2020-04-07 20:59:39 +02:00
parent 33472428e9
commit de1fa4a2da
7 changed files with 446 additions and 124 deletions

View File

@ -154,6 +154,7 @@ public:
_TextAlignment,
_AnnotationLineEnding,
_AnnotationBorderStyle,
_FileAttachmentIcon,
_Stamp
};
Q_ENUM(DataType)

View File

@ -290,6 +290,12 @@ void PDFExamplesGenerator::generateAnnotationsExample()
builder.createAnnotationStamp(page14, QRectF(210, 300, 100, 50), pdf::Stamp::Sold, "Title", "Subject", "Contents");
builder.createAnnotationStamp(page14, QRectF(210, 350, 100, 50), pdf::Stamp::TopSecret, "Title", "Subject", "Contents");
pdf::PDFObjectReference page15 = builder.appendPage(QRectF(0, 0, 400, 400));
builder.createAnnotationFileAttachment(page15, QPointF(50, 150), pdf::PDFObjectReference(), pdf::FileAttachmentIcon::PushPin, "Title", "File description");
builder.createAnnotationFileAttachment(page15, QPointF(50, 350), pdf::PDFObjectReference(), pdf::FileAttachmentIcon::Graph, "Title", "File description");
builder.createAnnotationFileAttachment(page15, QPointF(250, 150), pdf::PDFObjectReference(), pdf::FileAttachmentIcon::Paperclip, "Title", "File description");
builder.createAnnotationFileAttachment(page15, QPointF(250, 350), pdf::PDFObjectReference(), pdf::FileAttachmentIcon::Tag, "Title", "File description");
// Write result to a file
pdf::PDFDocument document = builder.build();
pdf::PDFDocumentWriter writer(nullptr);

View File

@ -447,14 +447,14 @@ PDFAnnotationPtr PDFAnnotation::parse(const PDFObjectStorage* storage, PDFObject
annotation->m_fileSpecification = PDFFileSpecification::parse(storage, dictionary->get("FS"));
constexpr const std::array<std::pair<const char*, PDFFileAttachmentAnnotation::Icon>, 4> icons = {
std::pair<const char*, PDFFileAttachmentAnnotation::Icon>{ "Graph", PDFFileAttachmentAnnotation::Icon::Graph },
std::pair<const char*, PDFFileAttachmentAnnotation::Icon>{ "Paperclip", PDFFileAttachmentAnnotation::Icon::Paperclip },
std::pair<const char*, PDFFileAttachmentAnnotation::Icon>{ "PushPin", PDFFileAttachmentAnnotation::Icon::PushPin },
std::pair<const char*, PDFFileAttachmentAnnotation::Icon>{ "Tag", PDFFileAttachmentAnnotation::Icon::Tag }
constexpr const std::array<std::pair<const char*, FileAttachmentIcon>, 4> icons = {
std::pair<const char*, FileAttachmentIcon>{ "Graph", FileAttachmentIcon::Graph },
std::pair<const char*, FileAttachmentIcon>{ "Paperclip", FileAttachmentIcon::Paperclip },
std::pair<const char*, FileAttachmentIcon>{ "PushPin", FileAttachmentIcon::PushPin },
std::pair<const char*, FileAttachmentIcon>{ "Tag", FileAttachmentIcon::Tag }
};
annotation->m_icon = loader.readEnumByName(dictionary->get("Name"), icons.begin(), icons.end(), PDFFileAttachmentAnnotation::Icon::PushPin);
annotation->m_icon = loader.readEnumByName(dictionary->get("Name"), icons.begin(), icons.end(), FileAttachmentIcon::PushPin);
}
else if (subtype == "Sound")
{
@ -2121,4 +2121,49 @@ void PDFStampAnnotation::draw(AnnotationDrawParameters& parameters) const
parameters.boundingRectangle.adjust(-penWidth, -penWidth, penWidth, penWidth);
}
void PDFFileAttachmentAnnotation::draw(AnnotationDrawParameters& parameters) const
{
QString text = "?";
switch (getIcon())
{
case FileAttachmentIcon::Graph:
text = QString::fromUtf16(u"\U0001F4C8");
break;
case FileAttachmentIcon::Paperclip:
text = QString::fromUtf16(u"\U0001F4CE");
break;
case FileAttachmentIcon::PushPin:
text = QString::fromUtf16(u"\U0001F4CC");
break;
case FileAttachmentIcon::Tag:
text = QString::fromUtf16(u"\U0001F3F7");
break;
default:
Q_ASSERT(false);
break;
}
const PDFReal opacity = getOpacity();
QColor strokeColor = QColor::fromRgbF(0.0, 0.0, 0.0, opacity);
constexpr const PDFReal rectSize = 24.0;
QPainter& painter = *parameters.painter;
QRectF rectangle = getRectangle();
rectangle.setSize(QSizeF(rectSize, rectSize));
QFont font = QApplication::font();
font.setPixelSize(16.0);
QPainterPath textPath;
textPath.addText(0.0, 0.0, font, text);
textPath = QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0).map(textPath);
QRectF textBoundingRect = textPath.boundingRect();
QPointF offset = rectangle.center() - textBoundingRect.center();
textPath.translate(offset);
painter.fillPath(textPath, QBrush(strokeColor, Qt::SolidPattern));
parameters.boundingRectangle = rectangle;
}
} // namespace pdf

View File

@ -1001,6 +1001,14 @@ private:
bool m_opened = false;
};
enum class FileAttachmentIcon
{
Graph,
Paperclip,
PushPin,
Tag
};
/// File attachment annotation contains reference to (embedded or external) file.
/// So it is a link to specified file. Activating annotation enables user to view
/// or store attached file in the filesystem.
@ -1009,24 +1017,17 @@ class PDFFileAttachmentAnnotation : public PDFMarkupAnnotation
public:
inline explicit PDFFileAttachmentAnnotation() = default;
enum class Icon
{
Graph,
Paperclip,
PushPin,
Tag
};
virtual AnnotationType getType() const override { return AnnotationType::FileAttachment; }
virtual void draw(AnnotationDrawParameters& parameters) const override;
const PDFFileSpecification& getFileSpecification() const { return m_fileSpecification; }
Icon getIcon() const { return m_icon; }
FileAttachmentIcon getIcon() const { return m_icon; }
private:
friend static PDFAnnotationPtr PDFAnnotation::parse(const PDFObjectStorage* storage, PDFObject object);
PDFFileSpecification m_fileSpecification;
Icon m_icon = Icon::PushPin;
FileAttachmentIcon m_icon = FileAttachmentIcon::PushPin;
};
/// Sound annotation contains sound, which is played, when

View File

@ -219,6 +219,34 @@ void PDFObjectFactory::endDictionaryItem()
std::get<PDFDictionary>(dictionaryItem.object).addEntry(qMove(topItem.itemName), qMove(std::get<PDFObject>(topItem.object)));
}
PDFObjectFactory& PDFObjectFactory::operator<<(FileAttachmentIcon icon)
{
switch (icon)
{
case FileAttachmentIcon::Graph:
*this << WrapName("Graph");
break;
case FileAttachmentIcon::Paperclip:
*this << WrapName("Paperclip");
break;
case FileAttachmentIcon::PushPin:
*this << WrapName("PushPin");
break;
case FileAttachmentIcon::Tag:
*this << WrapName("Tag");
break;
default:
Q_ASSERT(false);
break;
}
return *this;
}
PDFObjectFactory& PDFObjectFactory::operator<<(Stamp stamp)
{
switch (stamp)
@ -1310,6 +1338,56 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationCircle(PDFObjectReference
}
PDFObjectReference PDFDocumentBuilder::createAnnotationFileAttachment(PDFObjectReference page,
QPointF position,
PDFObjectReference fileSpecification,
FileAttachmentIcon icon,
QString title,
QString description)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("FileAttachment");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << QRectF(position, QSizeF(32, 32));
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("FS");
objectBuilder << fileSpecification;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Name");
objectBuilder << icon;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("T");
objectBuilder << title;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Contents");
objectBuilder << description;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationReference = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationReference;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationReference);
return annotationReference;
}
PDFObjectReference PDFDocumentBuilder::createAnnotationFreeText(PDFObjectReference page,
QRectF rectangle,
QString title,
@ -2638,6 +2716,55 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationText(PDFObjectReference p
}
PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Underline");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << rectangle;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("CreationDate");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("C");
objectBuilder << color;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("QuadPoints");
objectBuilder.beginArray();
objectBuilder << rectangle.bottomLeft();
objectBuilder << rectangle.bottomRight();
objectBuilder << rectangle.topLeft();
objectBuilder << rectangle.topRight();
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationObject = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationObject;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;
}
PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color,
@ -2702,55 +2829,6 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectRefere
}
PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Underline");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << rectangle;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("CreationDate");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("C");
objectBuilder << color;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("QuadPoints");
objectBuilder.beginArray();
objectBuilder << rectangle.bottomLeft();
objectBuilder << rectangle.bottomRight();
objectBuilder << rectangle.topLeft();
objectBuilder << rectangle.topRight();
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationObject = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationObject;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;
}
PDFObjectReference PDFDocumentBuilder::createCatalog()
{
PDFObjectFactory objectBuilder;

View File

@ -112,6 +112,7 @@ public:
PDFObjectFactory& operator<<(AnnotationBorderStyle style);
PDFObjectFactory& operator<<(const PDFObject& object);
PDFObjectFactory& operator<<(Stamp stamp);
PDFObjectFactory& operator<<(FileAttachmentIcon icon);
/// Treat containers - write them as array
template<typename Container, typename ValueType = decltype(*std::begin(std::declval<Container>()))>
@ -331,6 +332,21 @@ public:
QString contents);
/// Creates a new file attachment annotation. This annotation needs file specification as parameter.
/// \param page Page to which is annotation added
/// \param position Position
/// \param fileSpecification File specification
/// \param icon Icon
/// \param title Title
/// \param description Description
PDFObjectReference createAnnotationFileAttachment(PDFObjectReference page,
QPointF position,
PDFObjectReference fileSpecification,
FileAttachmentIcon icon,
QString title,
QString description);
/// Free text annotation displays text directly on a page. Text appears directly on the page, in the
/// same way, as standard text in PDF document. Free text annotations are usually used to comment
/// the document. Free text annotation can also have callout line, with, or without a knee.
@ -742,6 +758,16 @@ public:
bool open);
/// Text markup annotation is used to underline text. It is a markup annotation, so it can contain
/// window to be opened (and commented).
/// \param page Page to which is annotation added
/// \param rectangle Area in which is markup displayed
/// \param color Color
PDFObjectReference createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color);
/// Text markup annotation is used to underline text. It is a markup annotation, so it can contain
/// window to be opened (and commented).
/// \param page Page to which is annotation added
@ -758,16 +784,6 @@ public:
QString contents);
/// Text markup annotation is used to underline text. It is a markup annotation, so it can contain
/// window to be opened (and commented).
/// \param page Page to which is annotation added
/// \param rectangle Area in which is markup displayed
/// \param color Color
PDFObjectReference createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color);
/// Creates empty catalog. This function is used, when a new document is being created. Do not call
/// this function manually.
PDFObjectReference createCatalog();

View File

@ -617,6 +617,181 @@ return annotationObject;</property>
<property name="functionDescription">Circle annotation displays ellipse (or circle). Circle border/fill color can be defined, along with border width. Popup annotation can be attached to this annotation.</property>
<property name="returnType">_PDFObjectReference</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">page</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Page to which is annotation added</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">position</property>
<property name="parameterType">_QPointF</property>
<property name="parameterDescription">Position</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">fileSpecification</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">File specification</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">icon</property>
<property name="parameterType">_FileAttachmentIcon</property>
<property name="parameterDescription">Icon</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">title</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Title</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">description</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Description</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">Type</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Annot")</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("FileAttachment")</property>
</QObject>
<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">QRectF(position, QSizeF(32, 32))</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">FS</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">fileSpecification</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Name</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">icon</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">T</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">title</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Contents</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">description</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">annotationReference</property>
<property name="variableType">_PDFObjectReference</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">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">annotationReference</property>
</QObject>
</property>
<property name="dictionaryItemName">Annots</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></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">pageAnnots</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">appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationReference);
return annotationReference;</property>
</QObject>
</property>
<property name="functionType">Annotations</property>
<property name="functionName">createAnnotationFileAttachment</property>
<property name="functionDescription">Creates a new file attachment annotation. This annotation needs file specification as parameter.</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
@ -5044,27 +5219,6 @@ return annotationObject;</property>
<property name="parameterType">_QColor</property>
<property name="parameterDescription">Color</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">title</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Title</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">subject</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Subject</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">contents</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Contents</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
@ -5105,13 +5259,6 @@ return annotationObject;</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">M</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
@ -5126,27 +5273,6 @@ return annotationObject;</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">color</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">T</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">title</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Contents</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">contents</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subj</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">subject</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
@ -5248,6 +5374,27 @@ return annotationObject;</property>
<property name="parameterType">_QColor</property>
<property name="parameterDescription">Color</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">title</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Title</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">subject</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Subject</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">contents</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Contents</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
@ -5288,6 +5435,13 @@ return annotationObject;</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">M</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
@ -5302,6 +5456,27 @@ return annotationObject;</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">color</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">T</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">title</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Contents</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">contents</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subj</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">subject</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">