diff --git a/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp b/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp index f9de467..74a751a 100644 --- a/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp +++ b/Pdf4QtLib/sources/pdfpagecontenteditortools.cpp @@ -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& 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 diff --git a/Pdf4QtLib/sources/pdfpagecontenteditortools.h b/Pdf4QtLib/sources/pdfpagecontenteditortools.h index 1a0c452..759870a 100644 --- a/Pdf4QtLib/sources/pdfpagecontenteditortools.h +++ b/Pdf4QtLib/sources/pdfpagecontenteditortools.h @@ -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& errors) const override; + +private: + void clear(); + void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint); + + PDFPickTool* m_pickTool; + PDFPageContentElementLine* m_element; + std::optional m_startPoint; +}; + } // namespace pdf #endif // PDFPAGECONTENTEDITORTOOLS_H diff --git a/Pdf4QtLib/sources/pdfpagecontentelements.cpp b/Pdf4QtLib/sources/pdfpagecontentelements.cpp index 9e5d997..49f33d8 100644 --- a/Pdf4QtLib/sources/pdfpagecontentelements.cpp +++ b/Pdf4QtLib/sources/pdfpagecontentelements.cpp @@ -21,7 +21,6 @@ #include #include #include -#include namespace pdf { @@ -202,7 +201,7 @@ QString PDFPageContentScene::getTooltip() const const std::optional& 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& errors) const + PDFInteger pageIndex, + const PDFPrecompiledPage* compiledPage, + PDFTextLayoutGetter& layoutGetter, + const QMatrix& pagePointToDevicePointMatrix, + QList& 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& 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 diff --git a/Pdf4QtLib/sources/pdfpagecontentelements.h b/Pdf4QtLib/sources/pdfpagecontentelements.h index 04f6bba..419cdae 100644 --- a/Pdf4QtLib/sources/pdfpagecontentelements.h +++ b/Pdf4QtLib/sources/pdfpagecontentelements.h @@ -22,6 +22,7 @@ #include #include +#include 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& 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> m_elements; + std::optional m_cursor; }; } // namespace pdf diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp index 6c58edd..6e07350 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp @@ -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 SignaturePlugin::getActions() const void SignaturePlugin::updateActions() { - + QAction* clearAction = m_actions[Clear]; + clearAction->setEnabled(!m_scene.isEmpty()); } void SignaturePlugin::updateGraphics() diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h index eae90b1..4a89083 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.h @@ -76,6 +76,9 @@ private: { RectangleTool, RoundedRectangleTool, + HorizontalLineTool, + VerticalLineTool, + LineTool, LastTool }; diff --git a/qt.conf b/qt.conf new file mode 100644 index 0000000..5cfc332 --- /dev/null +++ b/qt.conf @@ -0,0 +1,2 @@ +[Platforms] +WindowsArguments = fontengine=freetype \ No newline at end of file