mirror of https://github.com/JakubMelka/PDF4QT.git
Signature plugin: Accept/reject mark
This commit is contained in:
parent
b61fcff27d
commit
f4e00f2f03
|
@ -15,7 +15,7 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
QT += gui widgets xml
|
||||
QT += gui widgets xml svg
|
||||
|
||||
TARGET = Pdf4QtLib
|
||||
TEMPLATE = lib
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
|
||||
#include "pdfpagecontenteditortools.h"
|
||||
#include "pdfpagecontentelements.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QPen>
|
||||
#include <QPainter>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
@ -33,6 +35,32 @@ PDFCreatePCElementTool::PDFCreatePCElementTool(PDFDrawWidgetProxy* proxy,
|
|||
|
||||
}
|
||||
|
||||
QRectF PDFCreatePCElementTool::getRectangleFromPickTool(PDFPickTool* pickTool,
|
||||
const QMatrix& pagePointToDevicePointMatrix)
|
||||
{
|
||||
const std::vector<QPointF>& points = pickTool->getPickedPoints();
|
||||
if (points.empty())
|
||||
{
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
QPointF mousePoint = pagePointToDevicePointMatrix.inverted().map(pickTool->getSnappedPoint());
|
||||
QPointF point = points.front();
|
||||
qreal xMin = qMin(point.x(), mousePoint.x());
|
||||
qreal xMax = qMax(point.x(), mousePoint.x());
|
||||
qreal yMin = qMin(point.y(), mousePoint.y());
|
||||
qreal yMax = qMax(point.y(), mousePoint.y());
|
||||
qreal width = xMax - xMin;
|
||||
qreal height = yMax - yMin;
|
||||
|
||||
if (!qFuzzyIsNull(width) && !qFuzzyIsNull(height))
|
||||
{
|
||||
return QRectF(xMin, yMin, width, height);
|
||||
}
|
||||
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
PDFCreatePCElementRectangleTool::PDFCreatePCElementRectangleTool(PDFDrawWidgetProxy* proxy,
|
||||
PDFPageContentScene* scene,
|
||||
QAction* action,
|
||||
|
@ -77,28 +105,14 @@ void PDFCreatePCElementRectangleTool::drawPage(QPainter* painter,
|
|||
return;
|
||||
}
|
||||
|
||||
const std::vector<QPointF>& points = m_pickTool->getPickedPoints();
|
||||
if (points.empty())
|
||||
QRectF rectangle = getRectangleFromPickTool(m_pickTool, pagePointToDevicePointMatrix);
|
||||
if (!rectangle.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_element->setPageIndex(pageIndex);
|
||||
|
||||
QPointF mousePoint = pagePointToDevicePointMatrix.inverted().map(m_pickTool->getSnappedPoint());
|
||||
QPointF point = points.front();
|
||||
qreal xMin = qMin(point.x(), mousePoint.x());
|
||||
qreal xMax = qMax(point.x(), mousePoint.x());
|
||||
qreal yMin = qMin(point.y(), mousePoint.y());
|
||||
qreal yMax = qMax(point.y(), mousePoint.y());
|
||||
qreal width = xMax - xMin;
|
||||
qreal height = yMax - yMin;
|
||||
|
||||
if (!qFuzzyIsNull(width) && !qFuzzyIsNull(height))
|
||||
{
|
||||
QRectF rect(xMin, yMin, width, height);
|
||||
m_element->setRectangle(rect);
|
||||
}
|
||||
m_element->setRectangle(rectangle);
|
||||
|
||||
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
||||
}
|
||||
|
@ -221,4 +235,78 @@ void PDFCreatePCElementLineTool::onPointPicked(PDFInteger pageIndex, QPointF pag
|
|||
setActive(false);
|
||||
}
|
||||
|
||||
PDFCreatePCElementSvgTool::PDFCreatePCElementSvgTool(PDFDrawWidgetProxy* proxy,
|
||||
PDFPageContentScene* scene,
|
||||
QAction* action,
|
||||
QByteArray content,
|
||||
QObject* parent) :
|
||||
BaseClass(proxy, scene, action, parent),
|
||||
m_pickTool(nullptr),
|
||||
m_element(nullptr)
|
||||
{
|
||||
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this);
|
||||
m_pickTool->setDrawSelectionRectangle(false);
|
||||
addTool(m_pickTool);
|
||||
connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreatePCElementSvgTool::onRectanglePicked);
|
||||
|
||||
m_element = new PDFPageContentSvgElement();
|
||||
m_element->setContent(content);
|
||||
|
||||
updateActions();
|
||||
}
|
||||
|
||||
PDFCreatePCElementSvgTool::~PDFCreatePCElementSvgTool()
|
||||
{
|
||||
delete m_element;
|
||||
}
|
||||
|
||||
void PDFCreatePCElementSvgTool::drawPage(QPainter* painter,
|
||||
PDFInteger pageIndex,
|
||||
const PDFPrecompiledPage* compiledPage,
|
||||
PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<PDFRenderError>& errors) const
|
||||
{
|
||||
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
||||
|
||||
if (pageIndex != m_pickTool->getPageIndex())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF rectangle = getRectangleFromPickTool(m_pickTool, pagePointToDevicePointMatrix);
|
||||
if (!rectangle.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_element->setPageIndex(pageIndex);
|
||||
m_element->setRectangle(rectangle);
|
||||
|
||||
{
|
||||
PDFPainterStateGuard guard(painter);
|
||||
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setPen(Qt::DotLine);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRect(rectangle);
|
||||
}
|
||||
|
||||
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
||||
}
|
||||
|
||||
void PDFCreatePCElementSvgTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle)
|
||||
{
|
||||
if (pageRectangle.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_element->setPageIndex(pageIndex);
|
||||
m_element->setRectangle(pageRectangle);
|
||||
m_scene->addElement(m_element->clone());
|
||||
|
||||
setActive(false);
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace pdf
|
|||
{
|
||||
|
||||
class PDFPageContentScene;
|
||||
class PDFPageContentSvgElement;
|
||||
class PDFPageContentElementLine;
|
||||
class PDFPageContentElementRectangle;
|
||||
|
||||
|
@ -36,6 +37,8 @@ public:
|
|||
QObject* parent);
|
||||
|
||||
protected:
|
||||
static QRectF getRectangleFromPickTool(PDFPickTool* pickTool, const QMatrix& pagePointToDevicePointMatrix);
|
||||
|
||||
PDFPageContentScene* m_scene;
|
||||
};
|
||||
|
||||
|
@ -69,6 +72,36 @@ private:
|
|||
PDFPageContentElementRectangle* m_element;
|
||||
};
|
||||
|
||||
/// Tool that displays SVG image
|
||||
class PDF4QTLIBSHARED_EXPORT PDFCreatePCElementSvgTool : public PDFCreatePCElementTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFCreatePCElementTool;
|
||||
|
||||
public:
|
||||
explicit PDFCreatePCElementSvgTool(PDFDrawWidgetProxy* proxy,
|
||||
PDFPageContentScene* scene,
|
||||
QAction* action,
|
||||
QByteArray content,
|
||||
QObject* parent);
|
||||
virtual ~PDFCreatePCElementSvgTool() override;
|
||||
|
||||
virtual void drawPage(QPainter* painter,
|
||||
PDFInteger pageIndex,
|
||||
const PDFPrecompiledPage* compiledPage,
|
||||
PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<PDFRenderError>& errors) const override;
|
||||
|
||||
private:
|
||||
void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle);
|
||||
|
||||
PDFPickTool* m_pickTool;
|
||||
PDFPageContentSvgElement* m_element;
|
||||
};
|
||||
|
||||
/// Tool that creates line element.
|
||||
class PDF4QTLIBSHARED_EXPORT PDFCreatePCElementLineTool : public PDFCreatePCElementTool
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <QPainter>
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
@ -293,4 +294,88 @@ void PDFPageContentElementLine::setLine(const QLineF& newLine)
|
|||
}
|
||||
}
|
||||
|
||||
PDFPageContentSvgElement::PDFPageContentSvgElement() :
|
||||
m_renderer(std::make_unique<QSvgRenderer>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDFPageContentSvgElement::~PDFPageContentSvgElement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDFPageContentSvgElement* PDFPageContentSvgElement::clone() const
|
||||
{
|
||||
PDFPageContentSvgElement* copy = new PDFPageContentSvgElement();
|
||||
copy->setPageIndex(getPageIndex());
|
||||
copy->setRectangle(getRectangle());
|
||||
copy->setContent(getContent());
|
||||
return copy;
|
||||
}
|
||||
|
||||
void PDFPageContentSvgElement::drawPage(QPainter* painter,
|
||||
PDFInteger pageIndex,
|
||||
const PDFPrecompiledPage* compiledPage,
|
||||
PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<PDFRenderError>& errors) const
|
||||
{
|
||||
Q_UNUSED(compiledPage);
|
||||
Q_UNUSED(layoutGetter);
|
||||
Q_UNUSED(errors);
|
||||
|
||||
if (pageIndex != getPageIndex() || !getRectangle().isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PDFPainterStateGuard guard(painter);
|
||||
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const QByteArray& PDFPageContentSvgElement::getContent() const
|
||||
{
|
||||
return m_content;
|
||||
}
|
||||
|
||||
void PDFPageContentSvgElement::setContent(const QByteArray& newContent)
|
||||
{
|
||||
if (m_content != newContent)
|
||||
{
|
||||
m_content = newContent;
|
||||
m_renderer->load(m_content);
|
||||
}
|
||||
}
|
||||
|
||||
const QRectF& PDFPageContentSvgElement::getRectangle() const
|
||||
{
|
||||
return m_rectangle;
|
||||
}
|
||||
|
||||
void PDFPageContentSvgElement::setRectangle(const QRectF& newRectangle)
|
||||
{
|
||||
m_rectangle = newRectangle;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
#include <QBrush>
|
||||
#include <QCursor>
|
||||
|
||||
class QSvgRenderer;
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
class PDFPageContentElement
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentElement
|
||||
{
|
||||
public:
|
||||
explicit PDFPageContentElement() = default;
|
||||
|
@ -49,7 +51,7 @@ protected:
|
|||
PDFInteger m_pageIndex = -1;
|
||||
};
|
||||
|
||||
class PDFPageContentStyledElement : public PDFPageContentElement
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentStyledElement : public PDFPageContentElement
|
||||
{
|
||||
public:
|
||||
explicit PDFPageContentStyledElement() = default;
|
||||
|
@ -66,7 +68,7 @@ protected:
|
|||
QBrush m_brush;
|
||||
};
|
||||
|
||||
class PDFPageContentElementRectangle : public PDFPageContentStyledElement
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentElementRectangle : public PDFPageContentStyledElement
|
||||
{
|
||||
public:
|
||||
virtual ~PDFPageContentElementRectangle() = default;
|
||||
|
@ -91,7 +93,7 @@ private:
|
|||
QRectF m_rectangle;
|
||||
};
|
||||
|
||||
class PDFPageContentElementLine : public PDFPageContentStyledElement
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentElementLine : public PDFPageContentStyledElement
|
||||
{
|
||||
public:
|
||||
virtual ~PDFPageContentElementLine() = default;
|
||||
|
@ -123,6 +125,33 @@ private:
|
|||
QLineF m_line;
|
||||
};
|
||||
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentSvgElement : public PDFPageContentElement
|
||||
{
|
||||
public:
|
||||
PDFPageContentSvgElement();
|
||||
virtual ~PDFPageContentSvgElement();
|
||||
|
||||
virtual PDFPageContentSvgElement* clone() const override;
|
||||
|
||||
virtual void drawPage(QPainter* painter,
|
||||
PDFInteger pageIndex,
|
||||
const PDFPrecompiledPage* compiledPage,
|
||||
PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<PDFRenderError>& errors) const override;
|
||||
|
||||
const QByteArray& getContent() const;
|
||||
void setContent(const QByteArray& newContent);
|
||||
|
||||
const QRectF& getRectangle() const;
|
||||
void setRectangle(const QRectF& newRectangle);
|
||||
|
||||
private:
|
||||
QRectF m_rectangle;
|
||||
QByteArray m_content;
|
||||
std::unique_ptr<QSvgRenderer> m_renderer;
|
||||
};
|
||||
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentScene : public QObject,
|
||||
public IDocumentDrawInterface,
|
||||
public IDrawWidgetInputInterface
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!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">
|
||||
<circle fill="#21E900" cx="12" cy="12" r="11.098"/>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M10.896,18.354c-0.24,0-0.474-0.087-0.658-0.247L6.28,14.649c-0.416-0.363-0.459-0.995-0.095-1.411
|
||||
c0.363-0.414,0.996-0.458,1.411-0.095l3.042,2.656l5.56-9.652c0.274-0.478,0.887-0.643,1.365-0.368
|
||||
c0.479,0.276,0.644,0.887,0.367,1.366l-6.167,10.707c-0.149,0.26-0.407,0.438-0.702,0.487
|
||||
C11.005,18.349,10.95,18.354,10.896,18.354z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 889 B |
|
@ -1,4 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/pdfplugins/signatureplugin">
|
||||
<file>accept-mark.svg</file>
|
||||
<file>reject-mark.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!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">
|
||||
<circle fill="#C80000" cx="12" cy="12" r="11.098"/>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M13.713,12l5.063-4.201c0.46-0.381,0.524-1.07,0.143-1.539c-0.394-0.466-1.077-0.531-1.54-0.141
|
||||
l-5.382,4.466L6.622,6.119C6.157,5.733,5.469,5.796,5.084,6.26C4.699,6.728,4.763,7.417,5.227,7.798L10.289,12l-5.062,4.204
|
||||
c-0.464,0.389-0.528,1.074-0.143,1.54c0.216,0.258,0.527,0.394,0.84,0.394c0.246,0,0.491-0.079,0.697-0.253l5.377-4.462
|
||||
l5.38,4.462c0.207,0.174,0.458,0.253,0.698,0.253c0.31,0,0.625-0.133,0.842-0.394c0.382-0.466,0.317-1.151-0.143-1.54L13.713,12z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -103,6 +103,24 @@ void SignaturePlugin::setWidget(pdf::PDFWidget* widget)
|
|||
m_actions[SignDigitally] = signDigitallyAction;
|
||||
m_actions[Ceritificates] = certificatesAction;
|
||||
|
||||
QFile acceptMarkFile(":/pdfplugins/signatureplugin/accept-mark.svg");
|
||||
QByteArray acceptMarkContent;
|
||||
if (acceptMarkFile.open(QFile::ReadOnly))
|
||||
{
|
||||
acceptMarkContent = acceptMarkFile.readAll();
|
||||
acceptMarkFile.close();
|
||||
}
|
||||
|
||||
QFile rejectMarkFile(":/pdfplugins/signatureplugin/reject-mark.svg");
|
||||
QByteArray rejectMarkContent;
|
||||
if (rejectMarkFile.open(QFile::ReadOnly))
|
||||
{
|
||||
rejectMarkContent = rejectMarkFile.readAll();
|
||||
rejectMarkFile.close();
|
||||
}
|
||||
|
||||
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[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);
|
||||
|
|
|
@ -74,6 +74,8 @@ private:
|
|||
|
||||
enum Tools
|
||||
{
|
||||
AcceptMarkTool,
|
||||
RejectMarkTool,
|
||||
RectangleTool,
|
||||
RoundedRectangleTool,
|
||||
HorizontalLineTool,
|
||||
|
|
Loading…
Reference in New Issue