mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Create annotations tool - line, polyline, polygon, ellipse
This commit is contained in:
		| @@ -22,6 +22,7 @@ | |||||||
|  |  | ||||||
| #include <QActionGroup> | #include <QActionGroup> | ||||||
| #include <QInputDialog> | #include <QInputDialog> | ||||||
|  | #include <QKeyEvent> | ||||||
|  |  | ||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
| @@ -162,7 +163,7 @@ void PDFCreateFreeTextTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageR | |||||||
|  |  | ||||||
|         QString userName = PDFSysUtils::getUserName(); |         QString userName = PDFSysUtils::getUserName(); | ||||||
|         PDFObjectReference page = getDocument()->getCatalog()->getPage(pageIndex)->getPageReference(); |         PDFObjectReference page = getDocument()->getCatalog()->getPage(pageIndex)->getPageReference(); | ||||||
|         modifier.getBuilder()->createAnnotationFreeText(page, pageRectangle, PDFSysUtils::getUserName(), QString(), text, TextAlignment(Qt::AlignLeft | Qt::AlignTop)); |         modifier.getBuilder()->createAnnotationFreeText(page, pageRectangle, userName, QString(), text, TextAlignment(Qt::AlignLeft | Qt::AlignTop)); | ||||||
|         modifier.markAnnotationsChanged(); |         modifier.markAnnotationsChanged(); | ||||||
|  |  | ||||||
|         if (modifier.finalize()) |         if (modifier.finalize()) | ||||||
| @@ -190,4 +191,411 @@ void PDFCreateAnnotationTool::updateActions() | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | PDFCreateLineTypeTool::PDFCreateLineTypeTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, PDFCreateLineTypeTool::Type type, QAction* action, QObject* parent) : | ||||||
|  |     BaseClass(proxy, action, parent), | ||||||
|  |     m_toolManager(toolManager), | ||||||
|  |     m_pickTool(nullptr), | ||||||
|  |     m_type(type), | ||||||
|  |     m_penWidth(1.0), | ||||||
|  |     m_strokeColor(Qt::red), | ||||||
|  |     m_fillColor(Qt::yellow) | ||||||
|  | { | ||||||
|  |     m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Points, this); | ||||||
|  |     addTool(m_pickTool); | ||||||
|  |     connect(m_pickTool, &PDFPickTool::pointPicked, this, &PDFCreateLineTypeTool::onPointPicked); | ||||||
|  |  | ||||||
|  |     m_fillColor.setAlphaF(0.2); | ||||||
|  |  | ||||||
|  |     updateActions(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::onPointPicked(PDFInteger pageIndex, QPointF pagePoint) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(pageIndex); | ||||||
|  |     Q_UNUSED(pagePoint); | ||||||
|  |  | ||||||
|  |     if (m_type == Type::Line && m_pickTool->getPickedPoints().size() == 2) | ||||||
|  |     { | ||||||
|  |         finishDefinition(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::finishDefinition() | ||||||
|  | { | ||||||
|  |     const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints(); | ||||||
|  |  | ||||||
|  |     switch (m_type) | ||||||
|  |     { | ||||||
|  |         case Type::Line: | ||||||
|  |         { | ||||||
|  |             if (pickedPoints.size() >= 2) | ||||||
|  |             { | ||||||
|  |                 PDFDocumentModifier modifier(getDocument()); | ||||||
|  |  | ||||||
|  |                 QString userName = PDFSysUtils::getUserName(); | ||||||
|  |                 PDFObjectReference page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex())->getPageReference(); | ||||||
|  |                 modifier.getBuilder()->createAnnotationLine(page, QRectF(), pickedPoints.front(), pickedPoints.back(), m_penWidth, m_fillColor, m_strokeColor, userName, QString(), QString(), AnnotationLineEnding::None, AnnotationLineEnding::None); | ||||||
|  |                 modifier.markAnnotationsChanged(); | ||||||
|  |  | ||||||
|  |                 if (modifier.finalize()) | ||||||
|  |                 { | ||||||
|  |                     emit m_toolManager->documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags())); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 setActive(false); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         case Type::PolyLine: | ||||||
|  |         { | ||||||
|  |             if (pickedPoints.size() >= 3) | ||||||
|  |             { | ||||||
|  |                 PDFDocumentModifier modifier(getDocument()); | ||||||
|  |  | ||||||
|  |                 QPolygonF polygon; | ||||||
|  |                 for (const QPointF& point : pickedPoints) | ||||||
|  |                 { | ||||||
|  |                     polygon << point; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 QString userName = PDFSysUtils::getUserName(); | ||||||
|  |                 PDFObjectReference page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex())->getPageReference(); | ||||||
|  |                 modifier.getBuilder()->createAnnotationPolyline(page, polygon, m_penWidth, m_fillColor, m_strokeColor, userName, QString(), QString(), AnnotationLineEnding::None, AnnotationLineEnding::None); | ||||||
|  |                 modifier.markAnnotationsChanged(); | ||||||
|  |  | ||||||
|  |                 if (modifier.finalize()) | ||||||
|  |                 { | ||||||
|  |                     emit m_toolManager->documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags())); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 setActive(false); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         case Type::Polygon: | ||||||
|  |         { | ||||||
|  |             if (pickedPoints.size() >= 3) | ||||||
|  |             { | ||||||
|  |                 PDFDocumentModifier modifier(getDocument()); | ||||||
|  |  | ||||||
|  |                 QPolygonF polygon; | ||||||
|  |                 for (const QPointF& point : pickedPoints) | ||||||
|  |                 { | ||||||
|  |                     polygon << point; | ||||||
|  |                 } | ||||||
|  |                 if (!polygon.isClosed()) | ||||||
|  |                 { | ||||||
|  |                     polygon << pickedPoints.front(); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 QString userName = PDFSysUtils::getUserName(); | ||||||
|  |                 PDFObjectReference page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex())->getPageReference(); | ||||||
|  |                 PDFObjectReference annotation = modifier.getBuilder()->createAnnotationPolygon(page, polygon, m_penWidth, m_fillColor, m_strokeColor, userName, QString(), QString()); | ||||||
|  |                 modifier.getBuilder()->setAnnotationFillOpacity(annotation, m_fillColor.alphaF()); | ||||||
|  |                 modifier.getBuilder()->updateAnnotationAppearanceStreams(annotation); | ||||||
|  |                 modifier.markAnnotationsChanged(); | ||||||
|  |  | ||||||
|  |                 if (modifier.finalize()) | ||||||
|  |                 { | ||||||
|  |                     emit m_toolManager->documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags())); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 setActive(false); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |             Q_ASSERT(false); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     m_pickTool->resetTool(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor PDFCreateLineTypeTool::getFillColor() const | ||||||
|  | { | ||||||
|  |     return m_fillColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::setFillColor(const QColor& fillColor) | ||||||
|  | { | ||||||
|  |     m_fillColor = fillColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor PDFCreateLineTypeTool::getStrokeColor() const | ||||||
|  | { | ||||||
|  |     return m_strokeColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::setStrokeColor(const QColor& strokeColor) | ||||||
|  | { | ||||||
|  |     m_strokeColor = strokeColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFReal PDFCreateLineTypeTool::getPenWidth() const | ||||||
|  | { | ||||||
|  |     return m_penWidth; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::setPenWidth(PDFReal penWidth) | ||||||
|  | { | ||||||
|  |     m_penWidth = penWidth; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::keyPressEvent(QWidget* widget, QKeyEvent* event) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(widget); | ||||||
|  |  | ||||||
|  |     switch (m_type) | ||||||
|  |     { | ||||||
|  |         case Type::PolyLine: | ||||||
|  |         case Type::Polygon: | ||||||
|  |         { | ||||||
|  |             if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) | ||||||
|  |             { | ||||||
|  |                 finishDefinition(); | ||||||
|  |                 event->accept(); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 event->ignore(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |             event->ignore(); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!event->isAccepted()) | ||||||
|  |     { | ||||||
|  |         BaseClass::keyPressEvent(widget, event); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::keyReleaseEvent(QWidget* widget, QKeyEvent* event) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(widget); | ||||||
|  |  | ||||||
|  |     switch (m_type) | ||||||
|  |     { | ||||||
|  |         case Type::PolyLine: | ||||||
|  |         case Type::Polygon: | ||||||
|  |         { | ||||||
|  |             if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) | ||||||
|  |             { | ||||||
|  |                 event->accept(); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 event->ignore(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |             event->ignore(); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!event->isAccepted()) | ||||||
|  |     { | ||||||
|  |         BaseClass::keyReleaseEvent(widget, event); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateLineTypeTool::drawPage(QPainter* painter, | ||||||
|  |                                      PDFInteger pageIndex, | ||||||
|  |                                      const PDFPrecompiledPage* compiledPage, | ||||||
|  |                                      PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                                      const QMatrix& pagePointToDevicePointMatrix, | ||||||
|  |                                      QList<PDFRenderError>& errors) const | ||||||
|  | { | ||||||
|  |     Q_UNUSED(pageIndex); | ||||||
|  |     Q_UNUSED(compiledPage); | ||||||
|  |     Q_UNUSED(layoutGetter); | ||||||
|  |     Q_UNUSED(errors); | ||||||
|  |  | ||||||
|  |     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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     QPointF mousePoint = pagePointToDevicePointMatrix.inverted().map(m_pickTool->getSnappedPoint()); | ||||||
|  |  | ||||||
|  |     painter->setWorldMatrix(pagePointToDevicePointMatrix, true); | ||||||
|  |  | ||||||
|  |     QPen pen(m_strokeColor); | ||||||
|  |     QBrush brush(m_fillColor, Qt::SolidPattern); | ||||||
|  |     pen.setWidthF(m_penWidth); | ||||||
|  |     painter->setPen(qMove(pen)); | ||||||
|  |     painter->setBrush(qMove(brush)); | ||||||
|  |     painter->setRenderHint(QPainter::Antialiasing); | ||||||
|  |  | ||||||
|  |     switch (m_type) | ||||||
|  |     { | ||||||
|  |         case Type::Line: | ||||||
|  |         case Type::PolyLine: | ||||||
|  |         { | ||||||
|  |             for (size_t i = 1; i < points.size(); ++i) | ||||||
|  |             { | ||||||
|  |                 painter->drawLine(points[i - 1], points[i]); | ||||||
|  |             } | ||||||
|  |             painter->drawLine(points.back(), mousePoint); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         case Type::Polygon: | ||||||
|  |         { | ||||||
|  |             QPainterPath path; | ||||||
|  |             path.moveTo(points.front()); | ||||||
|  |             for (size_t i = 1; i < points.size(); ++i) | ||||||
|  |             { | ||||||
|  |                 path.lineTo(points[i]); | ||||||
|  |             } | ||||||
|  |             path.lineTo(mousePoint); | ||||||
|  |             path.closeSubpath(); | ||||||
|  |  | ||||||
|  |             painter->drawPath(path); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |             Q_ASSERT(false); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFCreateEllipseTool::PDFCreateEllipseTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent) : | ||||||
|  |     BaseClass(proxy, action, parent), | ||||||
|  |     m_toolManager(toolManager), | ||||||
|  |     m_pickTool(nullptr), | ||||||
|  |     m_penWidth(1.0), | ||||||
|  |     m_strokeColor(Qt::red), | ||||||
|  |     m_fillColor(Qt::yellow) | ||||||
|  | { | ||||||
|  |     m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this); | ||||||
|  |     m_pickTool->setDrawSelectionRectangle(false); | ||||||
|  |     addTool(m_pickTool); | ||||||
|  |     connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreateEllipseTool::onRectanglePicked); | ||||||
|  |  | ||||||
|  |     m_fillColor.setAlphaF(0.2); | ||||||
|  |  | ||||||
|  |     updateActions(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFReal PDFCreateEllipseTool::getPenWidth() const | ||||||
|  | { | ||||||
|  |     return m_penWidth; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateEllipseTool::setPenWidth(PDFReal penWidth) | ||||||
|  | { | ||||||
|  |     m_penWidth = penWidth; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor PDFCreateEllipseTool::getStrokeColor() const | ||||||
|  | { | ||||||
|  |     return m_strokeColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateEllipseTool::setStrokeColor(const QColor& strokeColor) | ||||||
|  | { | ||||||
|  |     m_strokeColor = strokeColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QColor PDFCreateEllipseTool::getFillColor() const | ||||||
|  | { | ||||||
|  |     return m_fillColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateEllipseTool::setFillColor(const QColor& fillColor) | ||||||
|  | { | ||||||
|  |     m_fillColor = fillColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateEllipseTool::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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     QPointF mousePoint = pagePointToDevicePointMatrix.inverted().map(m_pickTool->getSnappedPoint()); | ||||||
|  |  | ||||||
|  |     painter->setWorldMatrix(pagePointToDevicePointMatrix, true); | ||||||
|  |  | ||||||
|  |     QPen pen(m_strokeColor); | ||||||
|  |     QBrush brush(m_fillColor, Qt::SolidPattern); | ||||||
|  |     pen.setWidthF(m_penWidth); | ||||||
|  |     painter->setPen(qMove(pen)); | ||||||
|  |     painter->setBrush(qMove(brush)); | ||||||
|  |     painter->setRenderHint(QPainter::Antialiasing); | ||||||
|  |  | ||||||
|  |     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); | ||||||
|  |         painter->drawEllipse(rect); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFCreateEllipseTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle) | ||||||
|  | { | ||||||
|  |     if (pageRectangle.isEmpty()) | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     PDFDocumentModifier modifier(getDocument()); | ||||||
|  |  | ||||||
|  |     QString userName = PDFSysUtils::getUserName(); | ||||||
|  |     PDFObjectReference page = getDocument()->getCatalog()->getPage(pageIndex)->getPageReference(); | ||||||
|  |     PDFObjectReference annotation = modifier.getBuilder()->createAnnotationCircle(page, pageRectangle, m_penWidth, m_fillColor, m_strokeColor, userName, QString(), QString()); | ||||||
|  |     modifier.getBuilder()->setAnnotationFillOpacity(annotation, m_fillColor.alphaF()); | ||||||
|  |     modifier.getBuilder()->updateAnnotationAppearanceStreams(annotation); | ||||||
|  |     modifier.markAnnotationsChanged(); | ||||||
|  |  | ||||||
|  |     if (modifier.finalize()) | ||||||
|  |     { | ||||||
|  |         emit m_toolManager->documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     setActive(false); | ||||||
|  | } | ||||||
|  |  | ||||||
| } // namespace pdf | } // namespace pdf | ||||||
|   | |||||||
| @@ -108,6 +108,89 @@ private: | |||||||
|     PDFPickTool* m_pickTool; |     PDFPickTool* m_pickTool; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// Tool that creates line/polyline/polygon annotations. | ||||||
|  | class PDFFORQTLIBSHARED_EXPORT PDFCreateLineTypeTool : public PDFCreateAnnotationTool | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     using BaseClass = PDFCreateAnnotationTool; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     enum class Type | ||||||
|  |     { | ||||||
|  |         Line, | ||||||
|  |         PolyLine, | ||||||
|  |         Polygon | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     explicit PDFCreateLineTypeTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, Type type, QAction* action, QObject* parent); | ||||||
|  |  | ||||||
|  |     virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override; | ||||||
|  |     virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override; | ||||||
|  |     virtual void drawPage(QPainter* painter, PDFInteger pageIndex, | ||||||
|  |                           const PDFPrecompiledPage* compiledPage, | ||||||
|  |                           PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                           const QMatrix& pagePointToDevicePointMatrix, | ||||||
|  |                           QList<PDFRenderError>& errors) const override; | ||||||
|  |  | ||||||
|  |     PDFReal getPenWidth() const; | ||||||
|  |     void setPenWidth(PDFReal penWidth); | ||||||
|  |  | ||||||
|  |     QColor getStrokeColor() const; | ||||||
|  |     void setStrokeColor(const QColor& strokeColor); | ||||||
|  |  | ||||||
|  |     QColor getFillColor() const; | ||||||
|  |     void setFillColor(const QColor& fillColor); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void onPointPicked(PDFInteger pageIndex, QPointF pagePoint); | ||||||
|  |     void finishDefinition(); | ||||||
|  |  | ||||||
|  |     PDFToolManager* m_toolManager; | ||||||
|  |     PDFPickTool* m_pickTool; | ||||||
|  |     Type m_type; | ||||||
|  |     PDFReal m_penWidth; | ||||||
|  |     QColor m_strokeColor; | ||||||
|  |     QColor m_fillColor; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// Tool that creates ellipse annotation. | ||||||
|  | class PDFFORQTLIBSHARED_EXPORT PDFCreateEllipseTool : public PDFCreateAnnotationTool | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     using BaseClass = PDFCreateAnnotationTool; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     explicit PDFCreateEllipseTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent); | ||||||
|  |  | ||||||
|  |     virtual void drawPage(QPainter* painter, PDFInteger pageIndex, | ||||||
|  |                           const PDFPrecompiledPage* compiledPage, | ||||||
|  |                           PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                           const QMatrix& pagePointToDevicePointMatrix, | ||||||
|  |                           QList<PDFRenderError>& errors) const override; | ||||||
|  |  | ||||||
|  |     PDFReal getPenWidth() const; | ||||||
|  |     void setPenWidth(PDFReal penWidth); | ||||||
|  |  | ||||||
|  |     QColor getStrokeColor() const; | ||||||
|  |     void setStrokeColor(const QColor& strokeColor); | ||||||
|  |  | ||||||
|  |     QColor getFillColor() const; | ||||||
|  |     void setFillColor(const QColor& fillColor); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle); | ||||||
|  |  | ||||||
|  |     PDFToolManager* m_toolManager; | ||||||
|  |     PDFPickTool* m_pickTool; | ||||||
|  |     PDFReal m_penWidth; | ||||||
|  |     QColor m_strokeColor; | ||||||
|  |     QColor m_fillColor; | ||||||
|  | }; | ||||||
|  |  | ||||||
| } // namespace pdf | } // namespace pdf | ||||||
|  |  | ||||||
| #endif // PDFADVANCEDTOOLS_H | #endif // PDFADVANCEDTOOLS_H | ||||||
|   | |||||||
| @@ -4073,6 +4073,21 @@ void PDFDocumentBuilder::setAnnotationContents(PDFObjectReference annotation, | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void PDFDocumentBuilder::setAnnotationFillOpacity(PDFObjectReference annotation, | ||||||
|  |                                                   PDFReal opacity) | ||||||
|  | { | ||||||
|  |     PDFObjectFactory objectBuilder; | ||||||
|  |  | ||||||
|  |     objectBuilder.beginDictionary(); | ||||||
|  |     objectBuilder.beginDictionaryItem("ca"); | ||||||
|  |     objectBuilder << opacity; | ||||||
|  |     objectBuilder.endDictionaryItem(); | ||||||
|  |     objectBuilder.endDictionary(); | ||||||
|  |     PDFObject annotationObject = objectBuilder.takeObject(); | ||||||
|  |     mergeTo(annotation, annotationObject); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void PDFDocumentBuilder::setAnnotationOpacity(PDFObjectReference annotation, | void PDFDocumentBuilder::setAnnotationOpacity(PDFObjectReference annotation, | ||||||
|                                               PDFReal opacity) |                                               PDFReal opacity) | ||||||
| { | { | ||||||
| @@ -4512,6 +4527,7 @@ void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount) | |||||||
|     updateDocumentInfo(qMove(updatedInfoDictionary)); |     updateDocumentInfo(qMove(updatedInfoDictionary)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* END GENERATED CODE */ | /* END GENERATED CODE */ | ||||||
|  |  | ||||||
| }   // namespace pdf | }   // namespace pdf | ||||||
|   | |||||||
| @@ -1161,6 +1161,13 @@ public: | |||||||
|                                QString contents); |                                QString contents); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// Sets constant fill opacity of annotation's graphics. | ||||||
|  |     /// \param annotation Annotation | ||||||
|  |     /// \param opacity Opacity (value must be in range from 0.0 to 1.0) | ||||||
|  |     void setAnnotationFillOpacity(PDFObjectReference annotation, | ||||||
|  |                                   PDFReal opacity); | ||||||
|  |  | ||||||
|  |  | ||||||
|     /// Sets constant opacity of annotation's graphics. |     /// Sets constant opacity of annotation's graphics. | ||||||
|     /// \param annotation Annotation |     /// \param annotation Annotation | ||||||
|     /// \param opacity Opacity (value must be in range from 0.0 to 1.0) |     /// \param opacity Opacity (value must be in range from 0.0 to 1.0) | ||||||
|   | |||||||
| @@ -996,7 +996,8 @@ void PDFMagnifierTool::setMagnifierSize(int magnifierSize) | |||||||
| PDFPickTool::PDFPickTool(PDFDrawWidgetProxy* proxy, PDFPickTool::Mode mode, QObject* parent) : | PDFPickTool::PDFPickTool(PDFDrawWidgetProxy* proxy, PDFPickTool::Mode mode, QObject* parent) : | ||||||
|     BaseClass(proxy, parent), |     BaseClass(proxy, parent), | ||||||
|     m_mode(mode), |     m_mode(mode), | ||||||
|     m_pageIndex(-1) |     m_pageIndex(-1), | ||||||
|  |     m_drawSelectionRectangle(true) | ||||||
| { | { | ||||||
|     setCursor((m_mode == Mode::Images) ? Qt::CrossCursor : Qt::BlankCursor); |     setCursor((m_mode == Mode::Images) ? Qt::CrossCursor : Qt::BlankCursor); | ||||||
|     m_snapper.setSnapPointPixelSize(PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 10)); |     m_snapper.setSnapPointPixelSize(PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 10)); | ||||||
| @@ -1018,7 +1019,7 @@ void PDFPickTool::drawPage(QPainter* painter, | |||||||
|     Q_UNUSED(errors); |     Q_UNUSED(errors); | ||||||
|  |  | ||||||
|     // If we are picking rectangles, then draw current selection rectangle |     // If we are picking rectangles, then draw current selection rectangle | ||||||
|     if (m_mode == Mode::Rectangles && m_pageIndex == pageIndex && !m_pickedPoints.empty()) |     if (m_mode == Mode::Rectangles && m_drawSelectionRectangle && m_pageIndex == pageIndex && !m_pickedPoints.empty()) | ||||||
|     { |     { | ||||||
|         QPoint p1 = pagePointToDevicePointMatrix.map(m_pickedPoints.back()).toPoint(); |         QPoint p1 = pagePointToDevicePointMatrix.map(m_pickedPoints.back()).toPoint(); | ||||||
|         QPoint p2 = m_snapper.getSnappedPoint().toPoint(); |         QPoint p2 = m_snapper.getSnappedPoint().toPoint(); | ||||||
| @@ -1206,6 +1207,11 @@ void PDFPickTool::buildSnapData() | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void PDFPickTool::setDrawSelectionRectangle(bool drawSelectionRectangle) | ||||||
|  | { | ||||||
|  |     m_drawSelectionRectangle = drawSelectionRectangle; | ||||||
|  | } | ||||||
|  |  | ||||||
| PDFScreenshotTool::PDFScreenshotTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) : | PDFScreenshotTool::PDFScreenshotTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) : | ||||||
|     BaseClass(proxy, action, parent), |     BaseClass(proxy, action, parent), | ||||||
|     m_pickTool(nullptr) |     m_pickTool(nullptr) | ||||||
|   | |||||||
| @@ -335,6 +335,11 @@ public: | |||||||
|  |  | ||||||
|     void resetTool(); |     void resetTool(); | ||||||
|  |  | ||||||
|  |     /// Turns on/off drawing of selection rectangle, if rectangle picking | ||||||
|  |     /// mode is active. | ||||||
|  |     /// \param drawSelectionRectangle Draw selection rectangle? | ||||||
|  |     void setDrawSelectionRectangle(bool drawSelectionRectangle); | ||||||
|  |  | ||||||
| signals: | signals: | ||||||
|     void pointPicked(PDFInteger pageIndex, QPointF pagePoint); |     void pointPicked(PDFInteger pageIndex, QPointF pagePoint); | ||||||
|     void rectanglePicked(PDFInteger pageIndex, QRectF pageRectangle); |     void rectanglePicked(PDFInteger pageIndex, QRectF pageRectangle); | ||||||
| @@ -351,6 +356,7 @@ private: | |||||||
|     QPoint m_mousePosition; |     QPoint m_mousePosition; | ||||||
|     PDFInteger m_pageIndex; |     PDFInteger m_pageIndex; | ||||||
|     std::vector<QPointF> m_pickedPoints; |     std::vector<QPointF> m_pickedPoints; | ||||||
|  |     bool m_drawSelectionRectangle; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Tool that makes screenshot of page area and copies it to the clipboard, | /// Tool that makes screenshot of page area and copies it to the clipboard, | ||||||
|   | |||||||
| @@ -339,6 +339,14 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|     m_toolManager->addTool(createHyperlinkTool); |     m_toolManager->addTool(createHyperlinkTool); | ||||||
|     pdf::PDFCreateFreeTextTool* createFreeTextTool = new pdf::PDFCreateFreeTextTool(m_pdfWidget->getDrawWidgetProxy(), m_toolManager, ui->actionInlineText, this); |     pdf::PDFCreateFreeTextTool* createFreeTextTool = new pdf::PDFCreateFreeTextTool(m_pdfWidget->getDrawWidgetProxy(), m_toolManager, ui->actionInlineText, this); | ||||||
|     m_toolManager->addTool(createFreeTextTool); |     m_toolManager->addTool(createFreeTextTool); | ||||||
|  |     pdf::PDFCreateLineTypeTool* createStraightLineTool = new pdf::PDFCreateLineTypeTool(m_pdfWidget->getDrawWidgetProxy(), m_toolManager, pdf::PDFCreateLineTypeTool::Type::Line, ui->actionCreateStraightLine, this); | ||||||
|  |     m_toolManager->addTool(createStraightLineTool); | ||||||
|  |     pdf::PDFCreateLineTypeTool* createPolylineTool = new pdf::PDFCreateLineTypeTool(m_pdfWidget->getDrawWidgetProxy(), m_toolManager, pdf::PDFCreateLineTypeTool::Type::PolyLine, ui->actionCreatePolyline, this); | ||||||
|  |     m_toolManager->addTool(createPolylineTool); | ||||||
|  |     pdf::PDFCreateLineTypeTool* createPolygonTool = new pdf::PDFCreateLineTypeTool(m_pdfWidget->getDrawWidgetProxy(), m_toolManager, pdf::PDFCreateLineTypeTool::Type::Polygon, ui->actionCreatePolygon, this); | ||||||
|  |     m_toolManager->addTool(createPolygonTool); | ||||||
|  |     pdf::PDFCreateEllipseTool* createEllipseTool = new pdf::PDFCreateEllipseTool(m_pdfWidget->getDrawWidgetProxy(), m_toolManager, ui->actionCreateEllipse, this); | ||||||
|  |     m_toolManager->addTool(createEllipseTool); | ||||||
|  |  | ||||||
|     m_annotationManager = new pdf::PDFWidgetAnnotationManager(m_pdfWidget->getDrawWidgetProxy(), this); |     m_annotationManager = new pdf::PDFWidgetAnnotationManager(m_pdfWidget->getDrawWidgetProxy(), this); | ||||||
|     connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::actionTriggered, this, &PDFViewerMainWindow::onActionTriggered); |     connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::actionTriggered, this, &PDFViewerMainWindow::onActionTriggered); | ||||||
|   | |||||||
| @@ -149,6 +149,10 @@ | |||||||
|     <addaction name="menuSticky_Note"/> |     <addaction name="menuSticky_Note"/> | ||||||
|     <addaction name="actionCreateHyperlink"/> |     <addaction name="actionCreateHyperlink"/> | ||||||
|     <addaction name="actionInlineText"/> |     <addaction name="actionInlineText"/> | ||||||
|  |     <addaction name="actionCreateStraightLine"/> | ||||||
|  |     <addaction name="actionCreatePolyline"/> | ||||||
|  |     <addaction name="actionCreatePolygon"/> | ||||||
|  |     <addaction name="actionCreateEllipse"/> | ||||||
|    </widget> |    </widget> | ||||||
|    <addaction name="menuFile"/> |    <addaction name="menuFile"/> | ||||||
|    <addaction name="menuEdit"/> |    <addaction name="menuEdit"/> | ||||||
| @@ -646,6 +650,38 @@ | |||||||
|     <string>Inline text</string> |     <string>Inline text</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|  |   <action name="actionCreateStraightLine"> | ||||||
|  |    <property name="checkable"> | ||||||
|  |     <bool>true</bool> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Straight Line</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionCreatePolyline"> | ||||||
|  |    <property name="checkable"> | ||||||
|  |     <bool>true</bool> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Polyline</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionCreatePolygon"> | ||||||
|  |    <property name="checkable"> | ||||||
|  |     <bool>true</bool> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Polygon</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionCreateEllipse"> | ||||||
|  |    <property name="checkable"> | ||||||
|  |     <bool>true</bool> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Ellipse</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  </widget> |  </widget> | ||||||
|  <layoutdefault spacing="6" margin="11"/> |  <layoutdefault spacing="6" margin="11"/> | ||||||
|  <resources> |  <resources> | ||||||
|   | |||||||
| @@ -8579,6 +8579,70 @@ return rootNodeReference;</property> | |||||||
|       <property name="functionDescription">Sets annotation contents.</property> |       <property name="functionDescription">Sets annotation contents.</property> | ||||||
|       <property name="returnType">_void</property> |       <property name="returnType">_void</property> | ||||||
|     </QObject> |     </QObject> | ||||||
|  |     <QObject class="codegen::GeneratedFunction"> | ||||||
|  |       <property name="objectName"></property> | ||||||
|  |       <property name="items"> | ||||||
|  |         <QObject class="codegen::GeneratedAction"> | ||||||
|  |           <property name="objectName"></property> | ||||||
|  |           <property name="items"> | ||||||
|  |             <QObject class="codegen::GeneratedParameter"> | ||||||
|  |               <property name="objectName"></property> | ||||||
|  |               <property name="items"/> | ||||||
|  |               <property name="parameterName">annotation</property> | ||||||
|  |               <property name="parameterType">_PDFObjectReference</property> | ||||||
|  |               <property name="parameterDescription">Annotation</property> | ||||||
|  |             </QObject> | ||||||
|  |             <QObject class="codegen::GeneratedParameter"> | ||||||
|  |               <property name="objectName"></property> | ||||||
|  |               <property name="items"/> | ||||||
|  |               <property name="parameterName">opacity</property> | ||||||
|  |               <property name="parameterType">_PDFReal</property> | ||||||
|  |               <property name="parameterDescription">Opacity (value must be in range from 0.0 to 1.0)</property> | ||||||
|  |             </QObject> | ||||||
|  |           </property> | ||||||
|  |           <property name="actionType">Parameters</property> | ||||||
|  |           <property name="variableName"></property> | ||||||
|  |           <property name="variableType">_void</property> | ||||||
|  |           <property name="code"></property> | ||||||
|  |         </QObject> | ||||||
|  |         <QObject class="codegen::GeneratedAction"> | ||||||
|  |           <property name="objectName"></property> | ||||||
|  |           <property name="items"> | ||||||
|  |             <QObject class="codegen::GeneratedPDFObject"> | ||||||
|  |               <property name="objectName"></property> | ||||||
|  |               <property name="items"> | ||||||
|  |                 <QObject class="codegen::GeneratedPDFObject"> | ||||||
|  |                   <property name="objectName"></property> | ||||||
|  |                   <property name="items"/> | ||||||
|  |                   <property name="dictionaryItemName">ca</property> | ||||||
|  |                   <property name="objectType">DictionaryItemSimple</property> | ||||||
|  |                   <property name="value">opacity</property> | ||||||
|  |                 </QObject> | ||||||
|  |               </property> | ||||||
|  |               <property name="dictionaryItemName"></property> | ||||||
|  |               <property name="objectType">Dictionary</property> | ||||||
|  |               <property name="value"></property> | ||||||
|  |             </QObject> | ||||||
|  |           </property> | ||||||
|  |           <property name="actionType">CreateObject</property> | ||||||
|  |           <property name="variableName">annotationObject</property> | ||||||
|  |           <property name="variableType">_PDFObject</property> | ||||||
|  |           <property name="code"></property> | ||||||
|  |         </QObject> | ||||||
|  |         <QObject class="codegen::GeneratedAction"> | ||||||
|  |           <property name="objectName"></property> | ||||||
|  |           <property name="items"/> | ||||||
|  |           <property name="actionType">Code</property> | ||||||
|  |           <property name="variableName"></property> | ||||||
|  |           <property name="variableType">_void</property> | ||||||
|  |           <property name="code">mergeTo(annotation, annotationObject);</property> | ||||||
|  |         </QObject> | ||||||
|  |       </property> | ||||||
|  |       <property name="functionType">Annotations</property> | ||||||
|  |       <property name="functionName">setAnnotationFillOpacity</property> | ||||||
|  |       <property name="functionDescription">Sets constant fill opacity of annotation's graphics.</property> | ||||||
|  |       <property name="returnType">_void</property> | ||||||
|  |     </QObject> | ||||||
|     <QObject class="codegen::GeneratedFunction"> |     <QObject class="codegen::GeneratedFunction"> | ||||||
|       <property name="objectName"></property> |       <property name="objectName"></property> | ||||||
|       <property name="items"> |       <property name="items"> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user