Signature plugin: Svg/Png custom image selection, bugfixing

This commit is contained in:
Jakub Melka 2022-04-15 17:59:24 +02:00
parent 72f08c7588
commit ad30920bdb
9 changed files with 187 additions and 83 deletions

View File

@ -232,6 +232,7 @@ void PDFPageContentEditorStyleSettings::setFontAlignment(Qt::Alignment alignment
radioButton->setChecked(false);
}
m_alignment = alignment;
QRadioButton* radioButton = qobject_cast<QRadioButton*>(m_alignmentMapper.mapping(int(alignment)));
radioButton->setChecked(true);

View File

@ -19,10 +19,13 @@
#include "pdfpagecontentelements.h"
#include "pdfpainterutils.h"
#include "pdftexteditpseudowidget.h"
#include "pdfdrawwidget.h"
#include <QPen>
#include <QPainter>
#include <QMouseEvent>
#include <QFileDialog>
#include <QImageReader>
#include <QGuiApplication>
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<QByteArray> 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())
{

View File

@ -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,
explicit PDFCreatePCElementImageTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
QByteArray content,
bool askSelectImage,
QObject* parent);
virtual ~PDFCreatePCElementSvgTool() override;
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.

View File

@ -27,6 +27,7 @@
#include <QMouseEvent>
#include <QSvgRenderer>
#include <QApplication>
#include <QImageReader>
namespace pdf
{
@ -1066,20 +1067,20 @@ void PDFPageContentElementLine::setLine(const QLineF& newLine)
}
}
PDFPageContentSvgElement::PDFPageContentSvgElement() :
PDFPageContentImageElement::PDFPageContentImageElement() :
m_renderer(std::make_unique<QSvgRenderer>())
{
}
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,6 +1108,8 @@ void PDFPageContentSvgElement::drawPage(QPainter* painter,
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
painter->setRenderHint(QPainter::Antialiasing);
if (m_renderer->isValid())
{
QRectF viewBox = m_renderer->viewBoxF();
if (!viewBox.isValid())
{
@ -1124,53 +1127,79 @@ void PDFPageContentSvgElement::drawPage(QPainter* painter,
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());
painter->translate(targetRenderBox.bottomLeft());
painter->scale(1.0, -1.0);
targetRenderBox.moveTopLeft(QPointF(0, 0));
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;
}

View File

@ -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<QSvgRenderer> m_renderer;
};

View File

@ -3,8 +3,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="#292D32" d="M21.943,17.113c0.127-0.611,0.19-1.328,0.201-2.186V9.072c-0.014-0.879-0.076-1.573-0.203-2.182
<path fill="#292D32" d="M21.943,17.113c0.127-0.611,0.19-1.328,0.201-2.186V9.072c-0.014-0.879-0.076-1.573-0.203-2.182
c-0.246-1.375-0.748-2.43-1.526-3.229c-0.581-0.611-1.371-1.077-2.347-1.386c-0.894-0.278-1.993-0.42-3.266-0.42L9.196,1.859
c-5.077,0-7.34,2.264-7.34,7.342v5.613c0,5.068,2.265,7.328,7.34,7.328h5.607c1.273,0,2.372-0.143,3.266-0.418
c0.971-0.301,1.738-0.752,2.35-1.379C21.193,19.549,21.691,18.492,21.943,17.113z M18.137,20.025
@ -12,13 +11,12 @@
c0-4.267,1.526-5.735,5.744-5.756l0,0h5.607c0.325,0,0.637,0.011,0.926,0.028c1,0.062,1.793,0.226,2.42,0.503
c1.181,0.501,1.877,1.414,2.199,2.872c0.129,0.624,0.191,1.35,0.2,2.223v5.859c-0.009,0.877-0.073,1.602-0.2,2.221
C20.025,18.615,19.325,19.527,18.137,20.025z"/>
<g>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M16.628,8.813H7.373c-0.553,0-1-0.448-1-1V7.125
c0-0.552,0.447-1,1-1h9.255c0.554,0,1,0.448,1,1v0.688C17.628,8.365,17.182,8.813,16.628,8.813z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M16.628,13.344H7.372c-0.552,0-1-0.447-1-1v-0.688
c0-0.553,0.448-1,1-1h9.256c0.554,0,1,0.448,1,1v0.688C17.628,12.896,17.182,13.344,16.628,13.344z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M16.628,17.875H7.373c-0.552,0-1-0.447-1-1v-0.688
c0-0.554,0.448-1,1-1h9.255c0.554,0,1,0.446,1,1v0.688C17.628,17.428,17.182,17.875,16.628,17.875z"/>
</g>
<g>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M8.813,7.372v9.255c0,0.553-0.448,1-1,1H7.125c-0.552,0-1-0.447-1-1
V7.372c0-0.554,0.448-1,1-1h0.688C8.365,6.372,8.813,6.818,8.813,7.372z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M13.344,7.372v9.256c0,0.552-0.447,1-1,1h-0.688
c-0.553,0-1-0.448-1-1V7.372c0-0.554,0.448-1,1-1h0.688C12.896,6.372,13.344,6.818,13.344,7.372z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M17.875,7.372v9.255c0,0.553-0.447,1-1,1h-0.688
c-0.554,0-1-0.447-1-1V7.372c0-0.554,0.446-1,1-1h0.688C17.428,6.372,17.875,6.818,17.875,7.372z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -3,7 +3,8 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<path fill="#292D32" d="M21.943,17.113c0.127-0.611,0.19-1.328,0.201-2.186V9.072c-0.014-0.879-0.076-1.573-0.203-2.182
<g>
<path fill="#292D32" d="M21.943,17.113c0.127-0.611,0.19-1.328,0.201-2.186V9.072c-0.014-0.879-0.076-1.573-0.203-2.182
c-0.246-1.375-0.748-2.43-1.526-3.229c-0.581-0.611-1.371-1.077-2.347-1.386c-0.894-0.278-1.993-0.42-3.266-0.42L9.196,1.859
c-5.077,0-7.34,2.264-7.34,7.342v5.613c0,5.068,2.265,7.328,7.34,7.328h5.607c1.273,0,2.372-0.143,3.266-0.418
c0.971-0.301,1.738-0.752,2.35-1.379C21.193,19.549,21.691,18.492,21.943,17.113z M18.137,20.025
@ -11,12 +12,13 @@
c0-4.267,1.526-5.735,5.744-5.756l0,0h5.607c0.325,0,0.637,0.011,0.926,0.028c1,0.062,1.793,0.226,2.42,0.503
c1.181,0.501,1.877,1.414,2.199,2.872c0.129,0.624,0.191,1.35,0.2,2.223v5.859c-0.009,0.877-0.073,1.602-0.2,2.221
C20.025,18.615,19.325,19.527,18.137,20.025z"/>
<g>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M8.813,7.372v9.255c0,0.553-0.448,1-1,1H7.125c-0.552,0-1-0.447-1-1
V7.372c0-0.554,0.448-1,1-1h0.688C8.365,6.372,8.813,6.818,8.813,7.372z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M13.344,7.372v9.256c0,0.552-0.447,1-1,1h-0.688
c-0.553,0-1-0.448-1-1V7.372c0-0.554,0.448-1,1-1h0.688C12.896,6.372,13.344,6.818,13.344,7.372z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M17.875,7.372v9.255c0,0.553-0.447,1-1,1h-0.688
c-0.554,0-1-0.447-1-1V7.372c0-0.554,0.446-1,1-1h0.688C17.428,6.372,17.875,6.818,17.875,7.372z"/>
<g>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M16.628,8.813H7.373c-0.553,0-1-0.448-1-1V7.125
c0-0.552,0.447-1,1-1h9.255c0.554,0,1,0.448,1,1v0.688C17.628,8.365,17.182,8.813,16.628,8.813z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M16.628,13.344H7.372c-0.552,0-1-0.447-1-1v-0.688
c0-0.553,0.448-1,1-1h9.256c0.554,0,1,0.448,1,1v0.688C17.628,12.896,17.182,13.344,16.628,13.344z"/>
<path fill="none" stroke="#292D32" stroke-miterlimit="10" d="M16.628,17.875H7.373c-0.552,0-1-0.447-1-1v-0.688
c0-0.554,0.448-1,1-1h9.255c0.554,0,1,0.446,1,1v0.688C17.628,17.428,17.182,17.875,16.628,17.875z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -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);
}

View File

@ -98,6 +98,7 @@ private:
VerticalLineTool,
LineTool,
DotTool,
ImageTool,
LastTool
};