diff --git a/CodeGenerator/codegenerator.h b/CodeGenerator/codegenerator.h index 2b28078..838e056 100644 --- a/CodeGenerator/codegenerator.h +++ b/CodeGenerator/codegenerator.h @@ -146,6 +146,8 @@ public: _QColor, _QVariant, _QPolygonF, + _QDateTime, + _QLocale, _TextAnnotationIcon, _LinkHighlightMode, _TextAlignment, diff --git a/PdfExampleGenerator/pdfexamplesgenerator.cpp b/PdfExampleGenerator/pdfexamplesgenerator.cpp index df91b5e..9a41edc 100644 --- a/PdfExampleGenerator/pdfexamplesgenerator.cpp +++ b/PdfExampleGenerator/pdfexamplesgenerator.cpp @@ -20,9 +20,16 @@ #include "pdfdocumentbuilder.h" #include "pdfdocumentwriter.h" +#include + void PDFExamplesGenerator::generateAnnotationsExample() { pdf::PDFDocumentBuilder builder; + builder.setDocumentTitle("Test document"); + builder.setDocumentAuthor("Jakub Melka"); + builder.setDocumentCreator(QCoreApplication::applicationName()); + builder.setDocumentSubject("Testing annotations"); + builder.setLanguage(QLocale::system()); pdf::PDFObjectReference page1 = builder.appendPage(QRectF(0, 0, 400, 400)); builder.createAnnotationText(page1, QRectF(50, 50, 24, 24), pdf::TextAnnotationIcon::Comment, "Title1", "Subject1", "Comment", false); diff --git a/PdfForQtLib/sources/pdfdocumentbuilder.cpp b/PdfForQtLib/sources/pdfdocumentbuilder.cpp index 1481ba5..02f5327 100644 --- a/PdfForQtLib/sources/pdfdocumentbuilder.cpp +++ b/PdfForQtLib/sources/pdfdocumentbuilder.cpp @@ -64,6 +64,12 @@ void PDFObjectFactory::endDictionaryItem() std::get(dictionaryItem.object).addEntry(qMove(topItem.itemName), qMove(std::get(topItem.object))); } +PDFObjectFactory& PDFObjectFactory::operator<<(const QDateTime& dateTime) +{ + addObject(PDFObject::createString(std::make_shared(PDFEncoding::converDateTimeToString(dateTime)))); + return *this; +} + PDFObjectFactory& PDFObjectFactory::operator<<(const QPointF& point) { *this << point.x(); @@ -497,6 +503,56 @@ PDFInteger PDFDocumentBuilder::getPageTreeRootChildCount() const return 0; } +PDFObjectReference PDFDocumentBuilder::getDocumentInfo() const +{ + if (const PDFDictionary* trailerDictionary = getDictionaryFromObject(m_storage.getTrailerDictionary())) + { + PDFObject object = trailerDictionary->get("Info"); + if (object.isReference()) + { + return object.getReference(); + } + } + + return PDFObjectReference(); +} + +PDFObjectReference PDFDocumentBuilder::getCatalogReference() const +{ + if (const PDFDictionary* trailerDictionary = getDictionaryFromObject(m_storage.getTrailerDictionary())) + { + PDFObject object = trailerDictionary->get("Root"); + if (object.isReference()) + { + return object.getReference(); + } + } + + return PDFObjectReference(); +} + +void PDFDocumentBuilder::updateDocumentInfo(PDFObject info) +{ + PDFObjectReference infoReference = getDocumentInfo(); + if (!infoReference.isValid()) + { + PDFObjectFactory objectFactory; + objectFactory.beginDictionary(); + objectFactory.endDictionary(); + infoReference = addObject(objectFactory.takeObject()); + + // Update the trailer dictionary + objectFactory.beginDictionary(); + objectFactory.beginDictionaryItem("Info"); + objectFactory << infoReference; + objectFactory.endDictionaryItem(); + objectFactory.endDictionary(); + m_storage.updateTrailerDictionary(objectFactory.takeObject()); + } + + mergeTo(infoReference, info); +} + /* START GENERATED CODE */ PDFObjectReference PDFDocumentBuilder::appendPage(QRectF mediaBox) @@ -1819,14 +1875,6 @@ PDFObject PDFDocumentBuilder::createTrailerDictionary(PDFObjectReference catalog { PDFObjectFactory objectBuilder; - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Size"); - objectBuilder << 1; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Root"); - objectBuilder << catalog; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Info"); objectBuilder.beginDictionary(); objectBuilder.beginDictionaryItem("Producer"); objectBuilder << getProducerString(); @@ -1838,6 +1886,16 @@ PDFObject PDFDocumentBuilder::createTrailerDictionary(PDFObjectReference catalog objectBuilder << WrapCurrentDateTime(); objectBuilder.endDictionaryItem(); objectBuilder.endDictionary(); + PDFObjectReference infoDictionary = addObject(objectBuilder.takeObject()); + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Size"); + objectBuilder << 1; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Root"); + objectBuilder << catalog; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Info"); + objectBuilder << infoDictionary; objectBuilder.endDictionaryItem(); objectBuilder.endDictionary(); PDFObject trailerDictionary = objectBuilder.takeObject(); @@ -1845,6 +1903,126 @@ PDFObject PDFDocumentBuilder::createTrailerDictionary(PDFObjectReference catalog } +void PDFDocumentBuilder::setDocumentAuthor(QString author) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Author"); + objectBuilder << author; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setDocumentCreationDate(QDateTime creationDate) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("CreationDate"); + objectBuilder << creationDate; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setDocumentCreator(QString creator) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Creator"); + objectBuilder << creator; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setDocumentKeywords(QString keywords) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Keywords"); + objectBuilder << keywords; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setDocumentProducer(QString producer) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Producer"); + objectBuilder << producer; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setDocumentSubject(QString subject) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Subject"); + objectBuilder << subject; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setDocumentTitle(QString title) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Title"); + objectBuilder << title; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject info = objectBuilder.takeObject(); + updateDocumentInfo(qMove(info)); +} + + +void PDFDocumentBuilder::setLanguage(QString language) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Lang"); + objectBuilder << language; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject updatedCatalog = objectBuilder.takeObject(); + mergeTo(getCatalogReference(), updatedCatalog); +} + + +void PDFDocumentBuilder::setLanguage(QLocale locale) +{ + PDFObjectFactory objectBuilder; + + setLanguage(locale.name()); +} + + void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount) { PDFObjectFactory objectBuilder; @@ -1853,7 +2031,8 @@ void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount) objectBuilder.beginDictionaryItem("Size"); objectBuilder << objectCount; objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Info"); + objectBuilder.endDictionary(); + PDFObject trailerDictionary = objectBuilder.takeObject(); objectBuilder.beginDictionary(); objectBuilder.beginDictionaryItem("Producer"); objectBuilder << getProducerString(); @@ -1862,10 +2041,9 @@ void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount) objectBuilder << WrapCurrentDateTime(); objectBuilder.endDictionaryItem(); objectBuilder.endDictionary(); - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObject trailerDictionary = objectBuilder.takeObject(); + PDFObject updatedInfoDictionary = objectBuilder.takeObject(); m_storage.updateTrailerDictionary(qMove(trailerDictionary)); + updateDocumentInfo(qMove(updatedInfoDictionary)); } diff --git a/PdfForQtLib/sources/pdfdocumentbuilder.h b/PdfForQtLib/sources/pdfdocumentbuilder.h index f647d48..06bdfe4 100644 --- a/PdfForQtLib/sources/pdfdocumentbuilder.h +++ b/PdfForQtLib/sources/pdfdocumentbuilder.h @@ -106,6 +106,7 @@ public: PDFObjectFactory& operator<<(WrapString string); PDFObjectFactory& operator<<(AnnotationLineEnding lineEnding); PDFObjectFactory& operator<<(const QPointF& point); + PDFObjectFactory& operator<<(const QDateTime& dateTime); /// Treat containers - write them as array template()))> @@ -616,6 +617,53 @@ public: PDFObject createTrailerDictionary(PDFObjectReference catalog); + /// Set document author. + /// \param author Author + void setDocumentAuthor(QString author); + + + /// Set document creation date. + /// \param creationDate Creation date/time + void setDocumentCreationDate(QDateTime creationDate); + + + /// Set document creator. + /// \param creator Creator + void setDocumentCreator(QString creator); + + + /// Set document keywords. + /// \param keywords Keywords + void setDocumentKeywords(QString keywords); + + + /// Set document producer. + /// \param producer Producer + void setDocumentProducer(QString producer); + + + /// Set document subject. + /// \param subject Subject + void setDocumentSubject(QString subject); + + + /// Set document title. + /// \param title Title + void setDocumentTitle(QString title); + + + /// Set document language. + /// \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 = + /// english), and the latter two is country code (US - United States). + void setLanguage(QString language); + + + /// Set document language. + /// \param locale Locale, from which is language determined + void setLanguage(QLocale locale); + + /// This function is used to update trailer dictionary. Must be called each time the final document is /// being built. /// \param objectCount Number of objects (including empty ones) @@ -632,6 +680,9 @@ private: QString getProducerString() const; PDFObjectReference getPageTreeRoot() const; PDFInteger getPageTreeRootChildCount() const; + PDFObjectReference getDocumentInfo() const; + PDFObjectReference getCatalogReference() const; + void updateDocumentInfo(PDFObject info); PDFObjectStorage m_storage; PDFVersion m_version; diff --git a/generated_code_definition.xml b/generated_code_definition.xml index a83c741..8e18ace 100644 --- a/generated_code_definition.xml +++ b/generated_code_definition.xml @@ -4396,6 +4396,44 @@ return annotationObject; _void + + + + + + + + + + Producer + DictionaryItemSimple + getProducerString() + + + + + CreationDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + + ModDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + Dictionary + + + + CreateObject + infoDictionary + _PDFObjectReference + + @@ -4418,40 +4456,10 @@ return annotationObject; - - - - - - - - Producer - DictionaryItemSimple - getProducerString() - - - - - CreationDate - DictionaryItemSimple - WrapCurrentDateTime() - - - - - ModDate - DictionaryItemSimple - WrapCurrentDateTime() - - - - Dictionary - - - + Info - DictionaryItemComplex - + DictionaryItemSimple + infoDictionary @@ -4478,6 +4486,495 @@ return annotationObject; This function is used to create a new trailer dictionary, when blank document is created. Do not call this function manually. _PDFObject + + + + + + + + + + author + _QString + Author + + + Parameters + + _void + + + + + + + + + + + + Author + DictionaryItemSimple + author + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentAuthor + Set document author. + _void + + + + + + + + + + + creationDate + _QDateTime + Creation date/time + + + Parameters + + _void + + + + + + + + + + + + CreationDate + DictionaryItemSimple + creationDate + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentCreationDate + Set document creation date. + _void + + + + + + + + + + + creator + _QString + Creator + + + Parameters + + _void + + + + + + + + + + + + Creator + DictionaryItemSimple + creator + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentCreator + Set document creator. + _void + + + + + + + + + + + keywords + _QString + Keywords + + + Parameters + + _void + + + + + + + + + + + + Keywords + DictionaryItemSimple + keywords + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentKeywords + Set document keywords. + _void + + + + + + + + + + + producer + _QString + Producer + + + Parameters + + _void + + + + + + + + + + + + Producer + DictionaryItemSimple + producer + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentProducer + Set document producer. + _void + + + + + + + + + + + subject + _QString + Subject + + + Parameters + + _void + + + + + + + + + + + + Subject + DictionaryItemSimple + subject + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentSubject + Set document subject. + _void + + + + + + + + + + + title + _QString + Title + + + Parameters + + _void + + + + + + + + + + + + Title + DictionaryItemSimple + title + + + + Dictionary + + + + CreateObject + info + _PDFObject + + + + + + Code + + _void + updateDocumentInfo(qMove(info)); + + + Structure + setDocumentTitle + Set document title. + _void + + + + + + + + + + + language + _QString + 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 = english), and the latter two is country code (US - United States). + + + Parameters + + _void + + + + + + + + + + + + Lang + DictionaryItemSimple + language + + + + Dictionary + + + + CreateObject + updatedCatalog + _PDFObject + + + + + + Code + + _void + mergeTo(getCatalogReference(), updatedCatalog); + + + Structure + setLanguage + Set document language. + _void + + + + + + + + + + + locale + _QLocale + Locale, from which is language determined + + + Parameters + + _void + + + + + + Code + + _void + setLanguage(locale.name()); + + + Structure + setLanguage + Set document language. + _void + @@ -4510,36 +5007,6 @@ return annotationObject; DictionaryItemSimple objectCount - - - - - - - - - - Producer - DictionaryItemSimple - getProducerString() - - - - - ModDate - DictionaryItemSimple - WrapCurrentDateTime() - - - - Dictionary - - - - Info - DictionaryItemComplex - - Dictionary @@ -4551,13 +5018,45 @@ return annotationObject; _PDFObject + + + + + + + + + + Producer + DictionaryItemSimple + getProducerString() + + + + + ModDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + Dictionary + + + + CreateObject + updatedInfoDictionary + _PDFObject + + Code _void - m_storage.updateTrailerDictionary(qMove(trailerDictionary)); + m_storage.updateTrailerDictionary(qMove(trailerDictionary)); +updateDocumentInfo(qMove(updatedInfoDictionary)); Structure