summaryrefslogtreecommitdiff
path: root/src/pdfwidgets
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2023-02-06 15:50:13 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2023-03-17 12:35:30 +0100
commitf36f0d5202fee3b778290dd68d1c30911b75b5b4 (patch)
treee7177927488ec3695e55c2363877bc6668ff8524 /src/pdfwidgets
parent76b01c4aeab77c4ab4e052d31141e010b9a73111 (diff)
downloadqtwebengine-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.cpp80
-rw-r--r--src/pdfwidgets/qpdfview.h5
-rw-r--r--src/pdfwidgets/qpdfview_p.h4
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;