Signatures: line tool

This commit is contained in:
Jakub Melka 2022-02-13 19:46:09 +01:00
parent c58f11c2e4
commit b61fcff27d
7 changed files with 263 additions and 8 deletions

View File

@ -117,4 +117,108 @@ void PDFCreatePCElementRectangleTool::onRectanglePicked(PDFInteger pageIndex, QR
setActive(false);
}
PDFCreatePCElementLineTool::PDFCreatePCElementLineTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
bool isHorizontal,
bool isVertical,
QObject* parent) :
BaseClass(proxy, scene, action, parent),
m_pickTool(nullptr),
m_element(nullptr)
{
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Points, this);
m_pickTool->setDrawSelectionRectangle(false);
addTool(m_pickTool);
connect(m_pickTool, &PDFPickTool::pointPicked, this, &PDFCreatePCElementLineTool::onPointPicked);
QPen pen(Qt::SolidLine);
pen.setWidthF(2.0);
pen.setCapStyle(Qt::RoundCap);
PDFPageContentElementLine::LineGeometry geometry = PDFPageContentElementLine::LineGeometry::General;
if (isHorizontal)
{
geometry = PDFPageContentElementLine::LineGeometry::Horizontal;
}
if (isVertical)
{
geometry = PDFPageContentElementLine::LineGeometry::Vertical;
}
m_element = new PDFPageContentElementLine();
m_element->setBrush(Qt::NoBrush);
m_element->setPen(std::move(pen));
m_element->setGeometry(geometry);
updateActions();
}
PDFCreatePCElementLineTool::~PDFCreatePCElementLineTool()
{
delete m_element;
}
void PDFCreatePCElementLineTool::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() || !m_startPoint)
{
return;
}
m_element->setPageIndex(pageIndex);
QPointF startPoint = *m_startPoint;
QPointF endPoint = pagePointToDevicePointMatrix.inverted().map(m_pickTool->getSnappedPoint());
QLineF line(startPoint, endPoint);
if (!qFuzzyIsNull(line.length()))
{
m_element->setLine(line);
}
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
}
void PDFCreatePCElementLineTool::clear()
{
m_startPoint = std::nullopt;
}
void PDFCreatePCElementLineTool::onPointPicked(PDFInteger pageIndex, QPointF pagePoint)
{
if (!m_startPoint || m_element->getPageIndex() != pageIndex)
{
m_startPoint = pagePoint;
m_element->setPageIndex(pageIndex);
m_element->setLine(QLineF(pagePoint, pagePoint));
return;
}
if (qFuzzyCompare(m_startPoint.value().x(), pagePoint.x()) &&
qFuzzyCompare(m_startPoint.value().y(), pagePoint.y()))
{
// Jakub Melka: Point is same as the start point
clear();
return;
}
QLineF line = m_element->getLine();
line.setP2(pagePoint);
m_element->setLine(line);
m_scene->addElement(m_element->clone());
clear();
setActive(false);
}
} // namespace pdf

View File

@ -24,6 +24,7 @@ namespace pdf
{
class PDFPageContentScene;
class PDFPageContentElementLine;
class PDFPageContentElementRectangle;
class PDFCreatePCElementTool : public PDFWidgetTool
@ -68,6 +69,39 @@ private:
PDFPageContentElementRectangle* m_element;
};
/// Tool that creates line element.
class PDF4QTLIBSHARED_EXPORT PDFCreatePCElementLineTool : public PDFCreatePCElementTool
{
Q_OBJECT
private:
using BaseClass = PDFCreatePCElementTool;
public:
explicit PDFCreatePCElementLineTool(PDFDrawWidgetProxy* proxy,
PDFPageContentScene* scene,
QAction* action,
bool isHorizontal,
bool isVertical,
QObject* parent);
virtual ~PDFCreatePCElementLineTool() override;
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const override;
private:
void clear();
void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
PDFPickTool* m_pickTool;
PDFPageContentElementLine* m_element;
std::optional<QPointF> m_startPoint;
};
} // namespace pdf
#endif // PDFPAGECONTENTEDITORTOOLS_H

View File

@ -21,7 +21,6 @@
#include <QPainter>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QCursor>
namespace pdf
{
@ -202,7 +201,7 @@ QString PDFPageContentScene::getTooltip() const
const std::optional<QCursor>& PDFPageContentScene::getCursor() const
{
return std::nullopt;
return m_cursor;
}
int PDFPageContentScene::getInputPriority() const
@ -211,12 +210,87 @@ int PDFPageContentScene::getInputPriority() const
}
void PDFPageContentScene::drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const
{
for (const auto& element : m_elements)
{
if (element->getPageIndex() != pageIndex)
{
continue;
}
element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
}
}
PDFPageContentElementLine* PDFPageContentElementLine::clone() const
{
PDFPageContentElementLine* copy = new PDFPageContentElementLine();
copy->setPageIndex(getPageIndex());
copy->setPen(getPen());
copy->setBrush(getBrush());
copy->setGeometry(getGeometry());
copy->setLine(getLine());
return copy;
}
void PDFPageContentElementLine::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);
painter->drawLine(getLine());
}
PDFPageContentElementLine::LineGeometry PDFPageContentElementLine::getGeometry() const
{
return m_geometry;
}
void PDFPageContentElementLine::setGeometry(LineGeometry newGeometry)
{
m_geometry = newGeometry;
}
const QLineF& PDFPageContentElementLine::getLine() const
{
return m_line;
}
void PDFPageContentElementLine::setLine(const QLineF& newLine)
{
m_line = newLine;
if (m_geometry == LineGeometry::Horizontal)
{
m_line.setP2(QPointF(newLine.p2().x(), newLine.p1().y()));
}
if (m_geometry == LineGeometry::Vertical)
{
m_line.setP2(QPointF(newLine.p1().x(), newLine.p2().y()));
}
}
} // namespace pdf

View File

@ -22,6 +22,7 @@
#include <QPen>
#include <QBrush>
#include <QCursor>
namespace pdf
{
@ -90,6 +91,38 @@ private:
QRectF m_rectangle;
};
class PDFPageContentElementLine : public PDFPageContentStyledElement
{
public:
virtual ~PDFPageContentElementLine() = default;
virtual PDFPageContentElementLine* clone() const override;
enum class LineGeometry
{
General,
Horizontal,
Vertical
};
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const override;
LineGeometry getGeometry() const;
void setGeometry(LineGeometry newGeometry);
const QLineF& getLine() const;
void setLine(const QLineF& newLine);
private:
LineGeometry m_geometry = LineGeometry::General;
QLineF m_line;
};
class PDF4QTLIBSHARED_EXPORT PDFPageContentScene : public QObject,
public IDocumentDrawInterface,
public IDrawWidgetInputInterface
@ -140,6 +173,7 @@ signals:
private:
std::vector<std::unique_ptr<PDFPageContentElement>> m_elements;
std::optional<QCursor> m_cursor;
};
} // namespace pdf

View File

@ -105,6 +105,9 @@ void SignaturePlugin::setWidget(pdf::PDFWidget* widget)
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);
pdf::PDFToolManager* toolManager = widget->getToolManager();
for (pdf::PDFWidgetTool* tool : m_tools)
@ -156,7 +159,8 @@ std::vector<QAction*> SignaturePlugin::getActions() const
void SignaturePlugin::updateActions()
{
QAction* clearAction = m_actions[Clear];
clearAction->setEnabled(!m_scene.isEmpty());
}
void SignaturePlugin::updateGraphics()

View File

@ -76,6 +76,9 @@ private:
{
RectangleTool,
RoundedRectangleTool,
HorizontalLineTool,
VerticalLineTool,
LineTool,
LastTool
};

2
qt.conf Normal file
View File

@ -0,0 +1,2 @@
[Platforms]
WindowsArguments = fontengine=freetype