From b696d6dbfb8453948010ed786d9ab24bd3d1b485 Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Wed, 9 Sep 2020 13:52:30 +0200 Subject: [PATCH] Support '#page=' fragment to open at page Support the '#page=' fragment to specify which page to open the document at, in addition to the existing '#' syntax. For PDF, the '#page=' fragment is specified in RFC 8118, section 3. BUG: 406831 --- autotests/parttest.cpp | 21 +++++++++++++++++++++ part.cpp | 12 +++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/autotests/parttest.cpp b/autotests/parttest.cpp index f3e489b92..bcfdb3ff6 100644 --- a/autotests/parttest.cpp +++ b/autotests/parttest.cpp @@ -95,6 +95,7 @@ private slots: void testAdditionalActionTriggers(); void testTypewriterAnnotTool(); void testJumpToPage(); + void testOpenAtPage(); void testForwardBackwardNavigation(); void testTabletProximityBehavior(); void testOpenPrintPreview(); @@ -1794,6 +1795,26 @@ void PartTest::testJumpToPage() QCOMPARE(part.m_pageView->verticalScrollBar()->value(), pageWithSpaceTop - 4); } +void PartTest::testOpenAtPage() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/simple-multipage.pdf"); + QUrl url = QUrl::fromLocalFile(testFile); + Okular::Part part(nullptr, nullptr, QVariantList()); + + const uint targetPageNumA = 25; + const uint expectedPageA = targetPageNumA - 1; + url.setFragment(QString::number(targetPageNumA)); + part.openUrl(url); + QCOMPARE(part.m_document->currentPage(), expectedPageA); + + // 'page=' param as specified in RFC 3778 + const uint targetPageNumB = 15; + const uint expectedPageB = targetPageNumB - 1; + url.setFragment("page=" + QString::number(targetPageNumB)); + part.openUrl(url); + QCOMPARE(part.m_document->currentPage(), expectedPageB); +} + void PartTest::testForwardBackwardNavigation() { const QString testFile = QStringLiteral(KDESRCDIR "data/simple-multipage.pdf"); diff --git a/part.cpp b/part.cpp index 76fa567e8..e648fc65e 100644 --- a/part.cpp +++ b/part.cpp @@ -1670,7 +1670,17 @@ bool Part::openUrl(const QUrl &_url, bool swapInsteadOfOpening) if (url.hasFragment()) { const QString dest = url.fragment(QUrl::FullyDecoded); bool ok = true; - const int page = dest.toInt(&ok); + int page = dest.toInt(&ok); + + if (!ok) { + const QStringList parameters = dest.split(QChar('&')); + for (const QString ¶meter : parameters) { + if (parameter.startsWith(QStringLiteral("page="), Qt::CaseInsensitive)) { + page = dest.midRef(5).toInt(&ok); + } + } + } + if (ok) { Okular::DocumentViewport vp(page - 1); vp.rePos.enabled = true;