/* poppler-pdf-converter.cc: qt interface to poppler * Copyright (C) 2008, Pino Toscano * Copyright (C) 2008, 2009, 2020-2022, Albert Astals Cid * Copyright (C) 2020, Thorsten Behrens * Copyright (C) 2020, Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by Technische Universität Dresden * Copyright (C) 2021, Klarälvdalens Datakonsult AB, a KDAB Group company, . * Copyright (C) 2021, Zachary Travis * Copyright (C) 2021, Georgiy Sgibnev . Work sponsored by lab50.net. * Copyright (C) 2022, Martin * Copyright (C) 2022, Felix Jung * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "poppler-qt5.h" #include "poppler-annotation-helper.h" #include "poppler-annotation-private.h" #include "poppler-private.h" #include "poppler-converter-private.h" #include "poppler-qiodeviceoutstream-private.h" #include #include #include "Array.h" #include "Form.h" #include namespace Poppler { class PDFConverterPrivate : public BaseConverterPrivate { public: PDFConverterPrivate(); ~PDFConverterPrivate() override; PDFConverter::PDFOptions opts; }; PDFConverterPrivate::PDFConverterPrivate() : BaseConverterPrivate(), opts(nullptr) { } PDFConverterPrivate::~PDFConverterPrivate() = default; PDFConverter::PDFConverter(DocumentData *document) : BaseConverter(*new PDFConverterPrivate()) { Q_D(PDFConverter); d->document = document; } PDFConverter::~PDFConverter() { } void PDFConverter::setPDFOptions(PDFConverter::PDFOptions options) { Q_D(PDFConverter); d->opts = options; } PDFConverter::PDFOptions PDFConverter::pdfOptions() const { Q_D(const PDFConverter); return d->opts; } bool PDFConverter::convert() { Q_D(PDFConverter); d->lastError = NoError; if (d->document->locked) { d->lastError = FileLockedError; return false; } QIODevice *dev = d->openDevice(); if (!dev) { d->lastError = OpenOutputError; return false; } bool deleteFile = false; if (QFile *file = qobject_cast(dev)) { deleteFile = !file->exists(); } int errorCode = errNone; QIODeviceOutStream stream(dev); if (d->opts & WithChanges) { errorCode = d->document->doc->saveAs(&stream); } else { errorCode = d->document->doc->saveWithoutChangesAs(&stream); } d->closeDevice(); if (errorCode != errNone) { if (deleteFile) { qobject_cast(dev)->remove(); } if (errorCode == errOpenFile) { d->lastError = OpenOutputError; } else { d->lastError = NotSupportedInputFileError; } } return (errorCode == errNone); } bool PDFConverter::sign(const NewSignatureData &data) { Q_D(PDFConverter); d->lastError = NoError; if (d->document->locked) { d->lastError = FileLockedError; return false; } if (data.signatureText().isEmpty()) { qWarning() << "No signature text given"; return false; } ::PDFDoc *doc = d->document->doc; ::Page *destPage = doc->getPage(data.page() + 1); std::unique_ptr gSignatureText = std::unique_ptr(QStringToUnicodeGooString(data.signatureText())); std::unique_ptr gSignatureLeftText = std::unique_ptr(QStringToUnicodeGooString(data.signatureLeftText())); const auto reason = std::unique_ptr(data.reason().isEmpty() ? nullptr : QStringToUnicodeGooString(data.reason())); const auto location = std::unique_ptr(data.location().isEmpty() ? nullptr : QStringToUnicodeGooString(data.location())); const auto ownerPwd = std::optional(data.documentOwnerPassword().constData()); const auto userPwd = std::optional(data.documentUserPassword().constData()); return doc->sign(d->outputFileName.toUtf8().constData(), data.certNickname().toUtf8().constData(), data.password().toUtf8().constData(), QStringToGooString(data.fieldPartialName()), data.page() + 1, boundaryToPdfRectangle(destPage, data.boundingRectangle(), Annotation::FixedRotation), *gSignatureText, *gSignatureLeftText, data.fontSize(), data.leftFontSize(), convertQColor(data.fontColor()), data.borderWidth(), convertQColor(data.borderColor()), convertQColor(data.backgroundColor()), reason.get(), location.get(), data.imagePath().toStdString(), ownerPwd, userPwd); } struct PDFConverter::NewSignatureData::NewSignatureDataPrivate { NewSignatureDataPrivate() = default; QString certNickname; QString password; int page; QRectF boundingRectangle; QString signatureText; QString signatureLeftText; QString reason; QString location; double fontSize = 10.0; double leftFontSize = 20.0; QColor fontColor = Qt::red; QColor borderColor = Qt::red; double borderWidth = 1.5; QColor backgroundColor = QColor(240, 240, 240); QString partialName = QUuid::createUuid().toString(); QByteArray documentOwnerPassword; QByteArray documentUserPassword; QString imagePath; }; PDFConverter::NewSignatureData::NewSignatureData() : d(new NewSignatureDataPrivate()) { } PDFConverter::NewSignatureData::~NewSignatureData() { delete d; } QString PDFConverter::NewSignatureData::certNickname() const { return d->certNickname; } void PDFConverter::NewSignatureData::setCertNickname(const QString &certNickname) { d->certNickname = certNickname; } QString PDFConverter::NewSignatureData::password() const { return d->password; } void PDFConverter::NewSignatureData::setPassword(const QString &password) { d->password = password; } int PDFConverter::NewSignatureData::page() const { return d->page; } void PDFConverter::NewSignatureData::setPage(int page) { d->page = page; } QRectF PDFConverter::NewSignatureData::boundingRectangle() const { return d->boundingRectangle; } void PDFConverter::NewSignatureData::setBoundingRectangle(const QRectF &rect) { d->boundingRectangle = rect; } QString PDFConverter::NewSignatureData::signatureText() const { return d->signatureText; } void PDFConverter::NewSignatureData::setSignatureText(const QString &text) { d->signatureText = text; } QString PDFConverter::NewSignatureData::signatureLeftText() const { return d->signatureLeftText; } void PDFConverter::NewSignatureData::setSignatureLeftText(const QString &text) { d->signatureLeftText = text; } QString PDFConverter::NewSignatureData::reason() const { return d->reason; } void PDFConverter::NewSignatureData::setReason(const QString &reason) { d->reason = reason; } QString PDFConverter::NewSignatureData::location() const { return d->location; } void PDFConverter::NewSignatureData::setLocation(const QString &location) { d->location = location; } double PDFConverter::NewSignatureData::fontSize() const { return d->fontSize; } void PDFConverter::NewSignatureData::setFontSize(double fontSize) { d->fontSize = fontSize; } double PDFConverter::NewSignatureData::leftFontSize() const { return d->leftFontSize; } void PDFConverter::NewSignatureData::setLeftFontSize(double fontSize) { d->leftFontSize = fontSize; } QColor PDFConverter::NewSignatureData::fontColor() const { return d->fontColor; } void PDFConverter::NewSignatureData::setFontColor(const QColor &color) { d->fontColor = color; } QColor PDFConverter::NewSignatureData::borderColor() const { return d->borderColor; } void PDFConverter::NewSignatureData::setBorderColor(const QColor &color) { d->borderColor = color; } QColor PDFConverter::NewSignatureData::backgroundColor() const { return d->backgroundColor; } double PDFConverter::NewSignatureData::borderWidth() const { return d->borderWidth; } void PDFConverter::NewSignatureData::setBorderWidth(double width) { d->borderWidth = width; } void PDFConverter::NewSignatureData::setBackgroundColor(const QColor &color) { d->backgroundColor = color; } QString PDFConverter::NewSignatureData::fieldPartialName() const { return d->partialName; } void PDFConverter::NewSignatureData::setFieldPartialName(const QString &name) { d->partialName = name; } QByteArray PDFConverter::NewSignatureData::documentOwnerPassword() const { return d->documentOwnerPassword; } void PDFConverter::NewSignatureData::setDocumentOwnerPassword(const QByteArray &password) { d->documentOwnerPassword = password; } QByteArray PDFConverter::NewSignatureData::documentUserPassword() const { return d->documentUserPassword; } void PDFConverter::NewSignatureData::setDocumentUserPassword(const QByteArray &password) { d->documentUserPassword = password; } QString PDFConverter::NewSignatureData::imagePath() const { return d->imagePath; } void PDFConverter::NewSignatureData::setImagePath(const QString &path) { d->imagePath = path; } }