diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2023-02-06 15:50:13 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2023-03-17 12:35:30 +0100 |
commit | f36f0d5202fee3b778290dd68d1c30911b75b5b4 (patch) | |
tree | e7177927488ec3695e55c2363877bc6668ff8524 /src/pdfwidgets | |
parent | 76b01c4aeab77c4ab4e052d31141e010b9a73111 (diff) | |
download | qtwebengine-f36f0d5202fee3b778290dd68d1c30911b75b5b4.tar.gz |
Make QPdfLinkModel public and use in QPdfView
Now you can click links on pages in PDF documents in QPdfView.
Task-number: QTBUG-77511
Fixes: QTBUG-102760
Change-Id: I348dcfd906be088aa3fcbe53aec4628b521cc2f3
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'src/pdfwidgets')
-rw-r--r-- | src/pdfwidgets/qpdfview.cpp | 80 | ||||
-rw-r--r-- | src/pdfwidgets/qpdfview.h | 5 | ||||
-rw-r--r-- | src/pdfwidgets/qpdfview_p.h | 4 |
3 files changed, 88 insertions, 1 deletions
diff --git a/src/pdfwidgets/qpdfview.cpp b/src/pdfwidgets/qpdfview.cpp index 831b51515..ce49245e9 100644 --- a/src/pdfwidgets/qpdfview.cpp +++ b/src/pdfwidgets/qpdfview.cpp @@ -8,6 +8,7 @@ #include "qpdfpagerenderer.h" #include <QGuiApplication> +#include <QLoggingCategory> #include <QPainter> #include <QPaintEvent> #include <QPdfDocument> @@ -18,6 +19,9 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(qLcLink, "qt.pdf.links") +//#define DEBUG_LINKS + QPdfViewPrivate::QPdfViewPrivate(QPdfView *q) : q_ptr(q) , m_document(nullptr) @@ -241,6 +245,12 @@ qreal QPdfViewPrivate::yPositionForPage(int pageNumber) const return (*it).y(); } +QTransform QPdfViewPrivate::screenScaleTransform() const +{ + const qreal scale = m_screenResolution * m_zoomFactor; + return QTransform::fromScale(scale, scale); +} + void QPdfViewPrivate::updateDocumentLayout() { m_documentLayout = calculateDocumentLayout(); @@ -282,7 +292,7 @@ QPdfView::QPdfView(QWidget *parent) horizontalScrollBar()->setSingleStep(20); QScroller::grabGesture(this); - + setMouseTracking(true); d->calculateViewport(); } @@ -317,6 +327,7 @@ void QPdfView::setDocument(QPdfDocument *document) [d](){ d->documentStatusChanged(); }); d->m_pageRenderer->setDocument(d->m_document); + d->m_linkModel.setDocument(d->m_document); d->documentStatusChanged(); } @@ -510,6 +521,29 @@ void QPdfView::paintEvent(QPaintEvent *event) } else { d->m_pageRenderer->requestPage(page, pageGeometry.size() * devicePixelRatioF()); } + +#ifdef DEBUG_LINKS + const QTransform scaleTransform = d->screenScaleTransform(); + const QString fmt = u"page %1 @ %2, %3"_s; + d->m_linkModel.setPage(page); + const int linkCount = d->m_linkModel.rowCount({}); + for (int i = 0; i < linkCount; ++i) { + const QRectF linkBounds = scaleTransform.mapRect( + d->m_linkModel.data(d->m_linkModel.index(i), + int(QPdfLinkModel::Role::Rect)).toRectF()) + .translated(pageGeometry.topLeft()); + painter.setPen(Qt::blue); + painter.drawRect(linkBounds); + painter.setPen(Qt::red); + const QPoint loc = d->m_linkModel.data(d->m_linkModel.index(i), + int(QPdfLinkModel::Role::Location)).toPoint(); + // TODO maybe draw destination URL if that's what it is + painter.drawText(linkBounds.bottomLeft() + QPoint(2, -2), + fmt.arg(d->m_linkModel.data(d->m_linkModel.index(i), + int(QPdfLinkModel::Role::Page)).toInt()) + .arg(loc.x()).arg(loc.y())); + } +#endif } } } @@ -533,6 +567,50 @@ void QPdfView::scrollContentsBy(int dx, int dy) d->calculateViewport(); } +void QPdfView::mousePressEvent(QMouseEvent *event) +{ + Q_ASSERT(event->isAccepted()); +} + +void QPdfView::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QPdfView); + const QTransform screenInvTransform = d->screenScaleTransform().inverted(); + for (auto it = d->m_documentLayout.pageGeometries.cbegin(); it != d->m_documentLayout.pageGeometries.cend(); ++it) { + const int page = it.key(); + const QRect pageGeometry = it.value(); + if (pageGeometry.contains(event->position().toPoint())) { + const QPointF posInPoints = screenInvTransform.map(event->position() - pageGeometry.topLeft()); + d->m_linkModel.setPage(page); + auto dest = d->m_linkModel.linkAt(posInPoints); + setCursor(dest.isValid() ? Qt::PointingHandCursor : Qt::ArrowCursor); + if (dest.isValid()) + qCDebug(qLcLink) << event->position() << ":" << posInPoints << "pt ->" << dest; + } + } +} + +void QPdfView::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QPdfView); + const QTransform screenInvTransform = d->screenScaleTransform().inverted(); + for (auto it = d->m_documentLayout.pageGeometries.cbegin(); it != d->m_documentLayout.pageGeometries.cend(); ++it) { + const int page = it.key(); + const QRect pageGeometry = it.value(); + if (pageGeometry.contains(event->position().toPoint())) { + const QPointF posInPoints = screenInvTransform.map(event->position() - pageGeometry.topLeft()); + d->m_linkModel.setPage(page); + auto dest = d->m_linkModel.linkAt(posInPoints); + if (dest.isValid()) { + qCDebug(qLcLink) << event << ": jumping to" << dest; + d->m_pageNavigator->jump(dest.page(), dest.location(), dest.zoom()); + // TODO scroll and zoom to where the link tells us to + } + return; + } + } +} + QT_END_NAMESPACE #include "moc_qpdfview.cpp" diff --git a/src/pdfwidgets/qpdfview.h b/src/pdfwidgets/qpdfview.h index 5a4d7ed38..886ed697f 100644 --- a/src/pdfwidgets/qpdfview.h +++ b/src/pdfwidgets/qpdfview.h @@ -4,6 +4,8 @@ #ifndef QPDFVIEW_H #define QPDFVIEW_H +#include <QtPdf/qpdfdocument.h> +#include <QtPdf/qpdflink.h> #include <QtPdfWidgets/qtpdfwidgetsglobal.h> #include <QtWidgets/qabstractscrollarea.h> @@ -78,6 +80,9 @@ protected: void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; void scrollContentsBy(int dx, int dy) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; private: Q_DECLARE_PRIVATE(QPdfView) diff --git a/src/pdfwidgets/qpdfview_p.h b/src/pdfwidgets/qpdfview_p.h index 23e83e8eb..97dc3de4f 100644 --- a/src/pdfwidgets/qpdfview_p.h +++ b/src/pdfwidgets/qpdfview_p.h @@ -16,6 +16,7 @@ // #include "qpdfview.h" +#include "qpdflinkmodel.h" #include <QHash> #include <QPointer> @@ -44,6 +45,8 @@ public: qreal yPositionForPage(int page) const; + QTransform screenScaleTransform() const; // points to pixels + struct DocumentLayout { QSize documentSize; @@ -57,6 +60,7 @@ public: QPointer<QPdfDocument> m_document; QPdfPageNavigator* m_pageNavigator; QPdfPageRenderer *m_pageRenderer; + QPdfLinkModel m_linkModel; QPdfView::PageMode m_pageMode; QPdfView::ZoomMode m_zoomMode; |