Signature plugin

This commit is contained in:
Jakub Melka
2022-02-11 19:15:57 +01:00
parent 2c5aca7ea6
commit c58f11c2e4
17 changed files with 913 additions and 8 deletions

View File

@@ -659,7 +659,7 @@ void PDFCreateFreehandCurveTool::mousePressEvent(QWidget* widget, QMouseEvent* e
resetTool();
}
getProxy()->repaintNeeded();
emit getProxy()->repaintNeeded();
}
void PDFCreateFreehandCurveTool::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
@@ -1063,7 +1063,7 @@ void PDFCreateHighlightTextTool::setSelection(PDFTextSelection&& textSelection)
if (m_textSelection != textSelection)
{
m_textSelection = qMove(textSelection);
getProxy()->repaintNeeded();
emit getProxy()->repaintNeeded();
}
}

View File

@@ -166,7 +166,8 @@ private:
public:
explicit PDFCreateEllipseTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent);
virtual void drawPage(QPainter* painter, PDFInteger pageIndex,
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,

View File

@@ -0,0 +1,120 @@
// Copyright (C) 2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfpagecontenteditortools.h"
#include "pdfpagecontentelements.h"
#include <QPen>
namespace pdf
{
PDFCreatePCElementTool::PDFCreatePCElementTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
QObject* parent) :
PDFWidgetTool(proxy, action, parent),
m_scene(scene)
{
}
PDFCreatePCElementRectangleTool::PDFCreatePCElementRectangleTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
bool isRounded,
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, &PDFCreatePCElementRectangleTool::onRectanglePicked);
QPen pen(Qt::SolidLine);
pen.setWidthF(1.0);
m_element = new PDFPageContentElementRectangle();
m_element->setBrush(Qt::NoBrush);
m_element->setPen(std::move(pen));
m_element->setRounded(isRounded);
updateActions();
}
PDFCreatePCElementRectangleTool::~PDFCreatePCElementRectangleTool()
{
delete m_element;
}
void PDFCreatePCElementRectangleTool::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;
}
const std::vector<QPointF>& points = m_pickTool->getPickedPoints();
if (points.empty())
{
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->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
}
void PDFCreatePCElementRectangleTool::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

View File

@@ -0,0 +1,73 @@
// Copyright (C) 2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFPAGECONTENTEDITORTOOLS_H
#define PDFPAGECONTENTEDITORTOOLS_H
#include "pdfwidgettool.h"
namespace pdf
{
class PDFPageContentScene;
class PDFPageContentElementRectangle;
class PDFCreatePCElementTool : public PDFWidgetTool
{
public:
PDFCreatePCElementTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
QObject* parent);
protected:
PDFPageContentScene* m_scene;
};
/// Tool that creates rectangle element.
class PDF4QTLIBSHARED_EXPORT PDFCreatePCElementRectangleTool : public PDFCreatePCElementTool
{
Q_OBJECT
private:
using BaseClass = PDFCreatePCElementTool;
public:
explicit PDFCreatePCElementRectangleTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
bool isRounded,
QObject* parent);
virtual ~PDFCreatePCElementRectangleTool() 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;
PDFPageContentElementRectangle* m_element;
};
} // namespace pdf
#endif // PDFPAGECONTENTEDITORTOOLS_H

View File

@@ -0,0 +1,222 @@
// Copyright (C) 2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfpagecontentelements.h"
#include "pdfpainterutils.h"
#include <QPainter>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QCursor>
namespace pdf
{
PDFInteger PDFPageContentElement::getPageIndex() const
{
return m_pageIndex;
}
void PDFPageContentElement::setPageIndex(PDFInteger newPageIndex)
{
m_pageIndex = newPageIndex;
}
const QPen& PDFPageContentStyledElement::getPen() const
{
return m_pen;
}
void PDFPageContentStyledElement::setPen(const QPen& newPen)
{
m_pen = newPen;
}
const QBrush& PDFPageContentStyledElement::getBrush() const
{
return m_brush;
}
void PDFPageContentStyledElement::setBrush(const QBrush& newBrush)
{
m_brush = newBrush;
}
PDFPageContentElementRectangle* PDFPageContentElementRectangle::clone() const
{
PDFPageContentElementRectangle* copy = new PDFPageContentElementRectangle();
copy->setPageIndex(getPageIndex());
copy->setPen(getPen());
copy->setBrush(getBrush());
copy->setRectangle(getRectangle());
copy->setRounded(isRounded());
return copy;
}
bool PDFPageContentElementRectangle::isRounded() const
{
return m_rounded;
}
void PDFPageContentElementRectangle::setRounded(bool newRounded)
{
m_rounded = newRounded;
}
const QRectF& PDFPageContentElementRectangle::getRectangle() const
{
return m_rectangle;
}
void PDFPageContentElementRectangle::setRectangle(const QRectF& newRectangle)
{
m_rectangle = newRectangle;
}
void PDFPageContentElementRectangle::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())
{
return;
}
PDFPainterStateGuard guard(painter);
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
painter->setPen(getPen());
painter->setBrush(getBrush());
painter->setRenderHint(QPainter::Antialiasing);
QRectF rect = getRectangle();
if (isRounded())
{
qreal radius = qMin(rect.width(), rect.height()) * 0.25;
painter->drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize);
}
else
{
painter->drawRect(rect);
}
}
PDFPageContentScene::PDFPageContentScene(QObject* parent) :
QObject(parent)
{
}
PDFPageContentScene::~PDFPageContentScene()
{
}
void PDFPageContentScene::addElement(PDFPageContentElement* element)
{
m_elements.emplace_back(element);
emit sceneChanged();
}
void PDFPageContentScene::clear()
{
if (!m_elements.empty())
{
m_elements.clear();
emit sceneChanged();
}
}
void PDFPageContentScene::shortcutOverrideEvent(QWidget* widget, QKeyEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::keyPressEvent(QWidget* widget, QKeyEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::keyReleaseEvent(QWidget* widget, QKeyEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::mousePressEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
void PDFPageContentScene::wheelEvent(QWidget* widget, QWheelEvent* event)
{
Q_UNUSED(widget);
event->ignore();
}
QString PDFPageContentScene::getTooltip() const
{
return QString();
}
const std::optional<QCursor>& PDFPageContentScene::getCursor() const
{
return std::nullopt;
}
int PDFPageContentScene::getInputPriority() const
{
return ToolPriority + 1;
}
void PDFPageContentScene::drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const
{
}
} // namespace pdf

View File

@@ -0,0 +1,147 @@
// Copyright (C) 2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFPAGECONTENTELEMENTS_H
#define PDFPAGECONTENTELEMENTS_H
#include "pdfdocumentdrawinterface.h"
#include <QPen>
#include <QBrush>
namespace pdf
{
class PDFPageContentElement
{
public:
explicit PDFPageContentElement() = default;
virtual ~PDFPageContentElement() = default;
virtual PDFPageContentElement* clone() const = 0;
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const = 0;
PDFInteger getPageIndex() const;
void setPageIndex(PDFInteger newPageIndex);
protected:
PDFInteger m_pageIndex = -1;
};
class PDFPageContentStyledElement : public PDFPageContentElement
{
public:
explicit PDFPageContentStyledElement() = default;
virtual ~PDFPageContentStyledElement() = default;
const QPen& getPen() const;
void setPen(const QPen& newPen);
const QBrush& getBrush() const;
void setBrush(const QBrush& newBrush);
protected:
QPen m_pen;
QBrush m_brush;
};
class PDFPageContentElementRectangle : public PDFPageContentStyledElement
{
public:
virtual ~PDFPageContentElementRectangle() = default;
virtual PDFPageContentElementRectangle* clone() const override;
bool isRounded() const;
void setRounded(bool newRounded);
const QRectF& getRectangle() const;
void setRectangle(const QRectF& newRectangle);
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const override;
private:
bool m_rounded = false;
QRectF m_rectangle;
};
class PDF4QTLIBSHARED_EXPORT PDFPageContentScene : public QObject,
public IDocumentDrawInterface,
public IDrawWidgetInputInterface
{
Q_OBJECT
public:
explicit PDFPageContentScene(QObject* parent);
virtual ~PDFPageContentScene();
/// Add new element to page content scene, scene
/// takes ownership over the element.
/// \param element Element
void addElement(PDFPageContentElement* element);
/// Clear whole scene - remove all page content elements
void clear();
/// Returns true, if scene is empty
bool isEmpty() const { return m_elements.empty(); }
// IDrawWidgetInputInterface interface
public:
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event) override;
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
virtual void wheelEvent(QWidget* widget, QWheelEvent* event) override;
virtual QString getTooltip() const override;
virtual const std::optional<QCursor>& getCursor() const override;
virtual int getInputPriority() const override;
// IDocumentDrawInterface interface
public:
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const override;
signals:
/// This signal is emitted when scene has changed (including graphics)
void sceneChanged();
private:
std::vector<std::unique_ptr<PDFPageContentElement>> m_elements;
};
} // namespace pdf
#endif // PDFPAGECONTENTELEMENTS_H

View File

@@ -1233,7 +1233,7 @@ void PDFPickTool::resetTool()
m_snapper.clearReferencePoint();
buildSnapData();
getProxy()->repaintNeeded();
emit getProxy()->repaintNeeded();
}
void PDFPickTool::buildSnapData()

View File

@@ -344,8 +344,8 @@ public:
void setSelectionRectangleColor(QColor selectionRectangleColor);
signals:
void pointPicked(PDFInteger pageIndex, QPointF pagePoint);
void rectanglePicked(PDFInteger pageIndex, QRectF pageRectangle);
void pointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
void rectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle);
void imagePicked(const QImage& image);
protected: