From ad30920bdbb469f9b64cceada113f4dbec2d6922 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Fri, 15 Apr 2022 17:59:24 +0200 Subject: [PATCH] Signature plugin: Svg/Png custom image selection, bugfixing --- .../pdfpagecontenteditorstylesettings.cpp | 1 + .../sources/pdfpagecontenteditortools.cpp | 82 ++++++++++++++++-- Pdf4QtLib/sources/pdfpagecontenteditortools.h | 27 +++--- Pdf4QtLib/sources/pdfpagecontentelements.cpp | 83 +++++++++++++------ Pdf4QtLib/sources/pdfpagecontentelements.h | 9 +- Pdf4QtViewer/resources/pce-layout-h.svg | 30 ++++--- Pdf4QtViewer/resources/pce-layout-v.svg | 30 +++---- .../SignaturePlugin/signatureplugin.cpp | 7 +- .../SignaturePlugin/signatureplugin.h | 1 + 9 files changed, 187 insertions(+), 83 deletions(-) diff --git a/Pdf4QtLib/sources/pdfpagecontenteditorstylesettings.cpp b/Pdf4QtLib/sources/pdfpagecontenteditorstylesettings.cpp index 268086a..45793fd 100644 --- a/Pdf4QtLib/sources/pdfpagecontenteditorstylesettings.cpp +++ b/Pdf4QtLib/sources/pdfpagecontenteditorstylesettings.cpp @@ -232,6 +232,7 @@ void PDFPageContentEditorStyleSettings::setFontAlignment(Qt::Alignment alignment radioButton->setChecked(false); } + m_alignment = alignment; QRadioButton* radioButton = qobject_cast(m_alignmentMapper.mapping(int(alignment))); radioButton->setChecked(true); diff --git a/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp b/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp index 1586688..0ba7779 100644 --- a/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp +++ b/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp @@ -19,10 +19,13 @@ #include "pdfpagecontentelements.h" #include "pdfpainterutils.h" #include "pdftexteditpseudowidget.h" +#include "pdfdrawwidget.h" #include #include #include +#include +#include #include namespace pdf @@ -303,32 +306,34 @@ void PDFCreatePCElementLineTool::onPointPicked(PDFInteger pageIndex, QPointF pag setActive(false); } -PDFCreatePCElementSvgTool::PDFCreatePCElementSvgTool(PDFDrawWidgetProxy* proxy, +PDFCreatePCElementImageTool::PDFCreatePCElementImageTool(PDFDrawWidgetProxy* proxy, PDFPageContentScene* scene, QAction* action, QByteArray content, + bool askSelectImage, QObject* parent) : BaseClass(proxy, scene, action, parent), m_pickTool(nullptr), - m_element(nullptr) + m_element(nullptr), + m_askSelectImage(askSelectImage) { m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this); m_pickTool->setDrawSelectionRectangle(false); addTool(m_pickTool); - connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreatePCElementSvgTool::onRectanglePicked); + connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreatePCElementImageTool::onRectanglePicked); - m_element = new PDFPageContentSvgElement(); + m_element = new PDFPageContentImageElement(); m_element->setContent(content); updateActions(); } -PDFCreatePCElementSvgTool::~PDFCreatePCElementSvgTool() +PDFCreatePCElementImageTool::~PDFCreatePCElementImageTool() { delete m_element; } -void PDFCreatePCElementSvgTool::drawPage(QPainter* painter, +void PDFCreatePCElementImageTool::drawPage(QPainter* painter, PDFInteger pageIndex, const PDFPrecompiledPage* compiledPage, PDFTextLayoutGetter& layoutGetter, @@ -363,17 +368,76 @@ void PDFCreatePCElementSvgTool::drawPage(QPainter* painter, m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors); } -const PDFPageContentElement* PDFCreatePCElementSvgTool::getElement() const +const PDFPageContentElement* PDFCreatePCElementImageTool::getElement() const { return m_element; } -PDFPageContentElement* PDFCreatePCElementSvgTool::getElement() +PDFPageContentElement* PDFCreatePCElementImageTool::getElement() { return m_element; } -void PDFCreatePCElementSvgTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle) +void PDFCreatePCElementImageTool::setActiveImpl(bool active) +{ + BaseClass::setActiveImpl(active); + + if (active && m_askSelectImage) + { + QTimer::singleShot(0, this, &PDFCreatePCElementImageTool::selectImage); + } +} + +void PDFCreatePCElementImageTool::selectImage() +{ + if (m_imageDirectory.isEmpty()) + { + QStringList pictureDirectiories = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); + if (!pictureDirectiories.isEmpty()) + { + m_imageDirectory = pictureDirectiories.last(); + } + else + { + m_imageDirectory = QDir::currentPath(); + } + } + + QList mimeTypes = QImageReader::supportedMimeTypes(); + QStringList mimeTypeFilters; + for (const QByteArray& mimeType : mimeTypes) + { + mimeTypeFilters.append(mimeType); + } + + QFileDialog dialog(getProxy()->getWidget(), tr("Select Image")); + dialog.setDirectory(m_imageDirectory); + dialog.setMimeTypeFilters(mimeTypeFilters); + dialog.selectMimeTypeFilter("image/svg+xml"); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + + if (dialog.exec() == QFileDialog::Accepted) + { + QString fileName = dialog.selectedFiles().constFirst(); + QFile file(fileName); + if (file.open(QFile::ReadOnly)) + { + m_element->setContent(file.readAll()); + file.close(); + } + else + { + setActive(false); + } + } + else + { + setActive(false); + } +} + +void PDFCreatePCElementImageTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle) { if (pageRectangle.isEmpty()) { diff --git a/Pdf4QtLib/sources/pdfpagecontenteditortools.h b/Pdf4QtLib/sources/pdfpagecontenteditortools.h index 7f274a2..568887b 100644 --- a/Pdf4QtLib/sources/pdfpagecontenteditortools.h +++ b/Pdf4QtLib/sources/pdfpagecontenteditortools.h @@ -25,7 +25,7 @@ namespace pdf class PDFPageContentScene; class PDFPageContentElement; -class PDFPageContentSvgElement; +class PDFPageContentImageElement; class PDFPageContentElementDot; class PDFPageContentElementLine; class PDFPageContentElementTextBox; @@ -90,8 +90,8 @@ private: PDFPageContentElementRectangle* m_element; }; -/// Tool that displays SVG image -class PDF4QTLIBSHARED_EXPORT PDFCreatePCElementSvgTool : public PDFCreatePCElementTool +/// Tool that displays SVG image (or raster image) +class PDF4QTLIBSHARED_EXPORT PDFCreatePCElementImageTool : public PDFCreatePCElementTool { Q_OBJECT @@ -99,12 +99,13 @@ private: using BaseClass = PDFCreatePCElementTool; public: - explicit PDFCreatePCElementSvgTool(PDFDrawWidgetProxy* proxy, - PDFPageContentScene* scene, - QAction* action, - QByteArray content, - QObject* parent); - virtual ~PDFCreatePCElementSvgTool() override; + explicit PDFCreatePCElementImageTool(PDFDrawWidgetProxy* proxy, + PDFPageContentScene* scene, + QAction* action, + QByteArray content, + bool askSelectImage, + QObject* parent); + virtual ~PDFCreatePCElementImageTool() override; virtual void drawPage(QPainter* painter, PDFInteger pageIndex, @@ -116,11 +117,17 @@ public: virtual const PDFPageContentElement* getElement() const override; virtual PDFPageContentElement* getElement() override; +protected: + virtual void setActiveImpl(bool active) override; + private: + void selectImage(); void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle); PDFPickTool* m_pickTool; - PDFPageContentSvgElement* m_element; + PDFPageContentImageElement* m_element; + bool m_askSelectImage; + QString m_imageDirectory; }; /// Tool that creates line element. diff --git a/Pdf4QtLib/sources/pdfpagecontentelements.cpp b/Pdf4QtLib/sources/pdfpagecontentelements.cpp index 800875d..c79f92f 100644 --- a/Pdf4QtLib/sources/pdfpagecontentelements.cpp +++ b/Pdf4QtLib/sources/pdfpagecontentelements.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace pdf { @@ -1066,20 +1067,20 @@ void PDFPageContentElementLine::setLine(const QLineF& newLine) } } -PDFPageContentSvgElement::PDFPageContentSvgElement() : +PDFPageContentImageElement::PDFPageContentImageElement() : m_renderer(std::make_unique()) { } -PDFPageContentSvgElement::~PDFPageContentSvgElement() +PDFPageContentImageElement::~PDFPageContentImageElement() { } -PDFPageContentSvgElement* PDFPageContentSvgElement::clone() const +PDFPageContentImageElement* PDFPageContentImageElement::clone() const { - PDFPageContentSvgElement* copy = new PDFPageContentSvgElement(); + PDFPageContentImageElement* copy = new PDFPageContentImageElement(); copy->setElementId(getElementId()); copy->setPageIndex(getPageIndex()); copy->setRectangle(getRectangle()); @@ -1087,7 +1088,7 @@ PDFPageContentSvgElement* PDFPageContentSvgElement::clone() const return copy; } -void PDFPageContentSvgElement::drawPage(QPainter* painter, +void PDFPageContentImageElement::drawPage(QPainter* painter, PDFInteger pageIndex, const PDFPrecompiledPage* compiledPage, PDFTextLayoutGetter& layoutGetter, @@ -1107,70 +1108,98 @@ void PDFPageContentSvgElement::drawPage(QPainter* painter, painter->setWorldMatrix(pagePointToDevicePointMatrix, true); painter->setRenderHint(QPainter::Antialiasing); - QRectF viewBox = m_renderer->viewBoxF(); - if (!viewBox.isValid()) + if (m_renderer->isValid()) { - return; + QRectF viewBox = m_renderer->viewBoxF(); + if (!viewBox.isValid()) + { + return; + } + + QRectF renderBox = getRectangle(); + QSizeF viewBoxSize = viewBox.size(); + QSizeF renderBoxSize = viewBoxSize.scaled(renderBox.size(), Qt::KeepAspectRatio); + QRectF targetRenderBox = QRectF(QPointF(), renderBoxSize); + targetRenderBox.moveCenter(renderBox.center()); + + painter->translate(targetRenderBox.bottomLeft()); + painter->scale(1.0, -1.0); + targetRenderBox.moveTopLeft(QPointF(0, 0)); + + m_renderer->render(painter, targetRenderBox); } + else if (!m_image.isNull()) + { + QRectF viewBox(QPointF(0, 0), m_image.size()); - QRectF renderBox = getRectangle(); - QSizeF viewBoxSize = viewBox.size(); - QSizeF renderBoxSize = viewBoxSize.scaled(renderBox.size(), Qt::KeepAspectRatio); - QRectF targetRenderBox = QRectF(QPointF(), renderBoxSize); - targetRenderBox.moveCenter(renderBox.center()); + QRectF renderBox = getRectangle(); + QSizeF viewBoxSize = viewBox.size(); + QSizeF renderBoxSize = viewBoxSize.scaled(renderBox.size(), Qt::KeepAspectRatio); + QRectF targetRenderBox = QRectF(QPointF(), renderBoxSize); + targetRenderBox.moveCenter(renderBox.center()); - painter->translate(targetRenderBox.bottomLeft()); - painter->scale(1.0, -1.0); - targetRenderBox.moveTopLeft(QPointF(0, 0)); + painter->translate(targetRenderBox.bottomLeft()); + painter->scale(1.0, -1.0); + targetRenderBox.moveTopLeft(QPointF(0, 0)); - m_renderer->render(painter, targetRenderBox); + painter->drawImage(targetRenderBox, m_image); + } } -uint PDFPageContentSvgElement::getManipulationMode(const QPointF& point, PDFReal snapPointDistanceThreshold) const +uint PDFPageContentImageElement::getManipulationMode(const QPointF& point, PDFReal snapPointDistanceThreshold) const { return getRectangleManipulationMode(getRectangle(), point, snapPointDistanceThreshold); } -void PDFPageContentSvgElement::performManipulation(uint mode, const QPointF& offset) +void PDFPageContentImageElement::performManipulation(uint mode, const QPointF& offset) { performRectangleManipulation(m_rectangle, mode, offset); } -QRectF PDFPageContentSvgElement::getBoundingBox() const +QRectF PDFPageContentImageElement::getBoundingBox() const { return getRectangle(); } -void PDFPageContentSvgElement::setSize(QSizeF size) +void PDFPageContentImageElement::setSize(QSizeF size) { performRectangleSetSize(m_rectangle, size); } -QString PDFPageContentSvgElement::getDescription() const +QString PDFPageContentImageElement::getDescription() const { return formatDescription(PDFTranslationContext::tr("SVG image")); } -const QByteArray& PDFPageContentSvgElement::getContent() const +const QByteArray& PDFPageContentImageElement::getContent() const { return m_content; } -void PDFPageContentSvgElement::setContent(const QByteArray& newContent) +void PDFPageContentImageElement::setContent(const QByteArray& newContent) { if (m_content != newContent) { m_content = newContent; - m_renderer->load(m_content); + if (!m_renderer->load(m_content)) + { + QByteArray imageData = m_content; + QBuffer buffer(&imageData); + buffer.open(QBuffer::ReadOnly); + + QImageReader reader(&buffer); + m_image = reader.read(); + buffer.close();; + } } } -const QRectF& PDFPageContentSvgElement::getRectangle() const +const QRectF& PDFPageContentImageElement::getRectangle() const { return m_rectangle; } -void PDFPageContentSvgElement::setRectangle(const QRectF& newRectangle) +void PDFPageContentImageElement::setRectangle(const QRectF& newRectangle) { m_rectangle = newRectangle; } diff --git a/Pdf4QtLib/sources/pdfpagecontentelements.h b/Pdf4QtLib/sources/pdfpagecontentelements.h index 20d3078..554b7ae 100644 --- a/Pdf4QtLib/sources/pdfpagecontentelements.h +++ b/Pdf4QtLib/sources/pdfpagecontentelements.h @@ -270,13 +270,13 @@ private: QPainterPath m_curve; }; -class PDF4QTLIBSHARED_EXPORT PDFPageContentSvgElement : public PDFPageContentElement +class PDF4QTLIBSHARED_EXPORT PDFPageContentImageElement : public PDFPageContentElement { public: - PDFPageContentSvgElement(); - virtual ~PDFPageContentSvgElement(); + PDFPageContentImageElement(); + virtual ~PDFPageContentImageElement(); - virtual PDFPageContentSvgElement* clone() const override; + virtual PDFPageContentImageElement* clone() const override; virtual void drawPage(QPainter* painter, PDFInteger pageIndex, @@ -302,6 +302,7 @@ public: private: QRectF m_rectangle; QByteArray m_content; + QImage m_image; std::unique_ptr m_renderer; }; diff --git a/Pdf4QtViewer/resources/pce-layout-h.svg b/Pdf4QtViewer/resources/pce-layout-h.svg index 91a63b2..059febe 100644 --- a/Pdf4QtViewer/resources/pce-layout-h.svg +++ b/Pdf4QtViewer/resources/pce-layout-h.svg @@ -3,22 +3,20 @@ + - - - - - - + + + diff --git a/Pdf4QtViewer/resources/pce-layout-v.svg b/Pdf4QtViewer/resources/pce-layout-v.svg index 059febe..91a63b2 100644 --- a/Pdf4QtViewer/resources/pce-layout-v.svg +++ b/Pdf4QtViewer/resources/pce-layout-v.svg @@ -3,20 +3,22 @@ - - - - + + + + + + diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp index c11057f..8e50da4 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp @@ -126,14 +126,15 @@ void SignaturePlugin::setWidget(pdf::PDFWidget* widget) m_tools[TextTool] = new pdf::PDFCreatePCElementTextTool(widget->getDrawWidgetProxy(), &m_scene, createTextAction, this); m_tools[FreehandCurveTool] = new pdf::PDFCreatePCElementFreehandCurveTool(widget->getDrawWidgetProxy(), &m_scene, createFreehandCurveAction, this); - m_tools[AcceptMarkTool] = new pdf::PDFCreatePCElementSvgTool(widget->getDrawWidgetProxy(), &m_scene, createAcceptMarkAction, acceptMarkContent, this); - m_tools[RejectMarkTool] = new pdf::PDFCreatePCElementSvgTool(widget->getDrawWidgetProxy(), &m_scene, createRejectMarkAction, rejectMarkContent, this); + m_tools[AcceptMarkTool] = new pdf::PDFCreatePCElementImageTool(widget->getDrawWidgetProxy(), &m_scene, createAcceptMarkAction, acceptMarkContent, false, this); + m_tools[RejectMarkTool] = new pdf::PDFCreatePCElementImageTool(widget->getDrawWidgetProxy(), &m_scene, createRejectMarkAction, rejectMarkContent, false, this); m_tools[RectangleTool] = new pdf::PDFCreatePCElementRectangleTool(widget->getDrawWidgetProxy(), &m_scene, createRectangleAction, false, this); m_tools[RoundedRectangleTool] = new pdf::PDFCreatePCElementRectangleTool(widget->getDrawWidgetProxy(), &m_scene, createRoundedRectangleAction, true, this); m_tools[HorizontalLineTool] = new pdf::PDFCreatePCElementLineTool(widget->getDrawWidgetProxy(), &m_scene, createHorizontalLineAction, true, false, this); m_tools[VerticalLineTool] = new pdf::PDFCreatePCElementLineTool(widget->getDrawWidgetProxy(), &m_scene, createVerticalLineAction, false, true, this); m_tools[LineTool] = new pdf::PDFCreatePCElementLineTool(widget->getDrawWidgetProxy(), &m_scene, createLineAction, false, false, this); m_tools[DotTool] = new pdf::PDFCreatePCElementDotTool(widget->getDrawWidgetProxy(), &m_scene, createDotAction, this); + m_tools[ImageTool] = new pdf::PDFCreatePCElementImageTool(widget->getDrawWidgetProxy(), &m_scene, createSvgImageAction, QByteArray(), true, this); pdf::PDFToolManager* toolManager = widget->getToolManager(); for (pdf::PDFWidgetTool* tool : m_tools) @@ -287,7 +288,7 @@ void SignaturePlugin::setActive(bool active) if (pdf::PDFWidgetTool* tool = m_widget->getToolManager()->getActiveTool()) { auto it = std::find(m_tools.cbegin(), m_tools.cend(), tool); - if (it == m_tools.cend()) + if (it != m_tools.cend()) { m_widget->getToolManager()->setActiveTool(nullptr); } diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h index cc6a156..cf25766 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h @@ -98,6 +98,7 @@ private: VerticalLineTool, LineTool, DotTool, + ImageTool, LastTool };