mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Signatures: line tool
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| @@ -217,6 +216,81 @@ void PDFPageContentScene::drawPage(QPainter* painter, | ||||
|                                    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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -76,6 +76,9 @@ private: | ||||
|     { | ||||
|         RectangleTool, | ||||
|         RoundedRectangleTool, | ||||
|         HorizontalLineTool, | ||||
|         VerticalLineTool, | ||||
|         LineTool, | ||||
|         LastTool | ||||
|     }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user