diff options
-rw-r--r-- | examples/pdfwidgets/pdfviewer/mainwindow.cpp | 17 | ||||
-rw-r--r-- | examples/pdfwidgets/pdfviewer/mainwindow.h | 3 | ||||
-rw-r--r-- | src/pdf/qpdfdocument.cpp | 17 | ||||
-rw-r--r-- | src/pdf/qpdfdocument.h | 1 | ||||
-rw-r--r-- | src/pdfwidgets/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/pdfwidgets/qpdfpageselector.cpp | 105 | ||||
-rw-r--r-- | src/pdfwidgets/qpdfpageselector.h | 44 | ||||
-rw-r--r-- | src/pdfwidgets/qpdfpageselector_p.h | 42 |
8 files changed, 222 insertions, 8 deletions
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp index 02caffa48..d7527a8d5 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp +++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp @@ -8,10 +8,10 @@ #include <QFileDialog> #include <QMessageBox> -#include <QSpinBox> #include <QPdfBookmarkModel> #include <QPdfDocument> #include <QPdfPageNavigator> +#include <QPdfPageSelector> #include <QStandardPaths> #include <QtMath> @@ -23,7 +23,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_zoomSelector(new ZoomSelector(this)) - , m_pageSelector(new QSpinBox(this)) + , m_pageSelector(new QPdfPageSelector(this)) , m_document(new QPdfDocument(this)) { ui->setupUi(this); @@ -32,9 +32,10 @@ MainWindow::MainWindow(QWidget *parent) ui->mainToolBar->insertWidget(ui->actionZoom_In, m_zoomSelector); ui->mainToolBar->insertWidget(ui->actionForward, m_pageSelector); - connect(m_pageSelector, &QSpinBox::valueChanged, this, &MainWindow::pageSelected); + connect(m_pageSelector, &QPdfPageSelector::valueChanged, this, &MainWindow::pageSelected); + m_pageSelector->setDocument(m_document); auto nav = ui->pdfView->pageNavigator(); - connect(nav, &QPdfPageNavigator::currentPageChanged, m_pageSelector, &QSpinBox::setValue); + connect(nav, &QPdfPageNavigator::currentPageChanged, m_pageSelector, &QPdfPageSelector::setValue); connect(nav, &QPdfPageNavigator::backAvailableChanged, ui->actionBack, &QAction::setEnabled); connect(nav, &QPdfPageNavigator::forwardAvailableChanged, ui->actionForward, &QAction::setEnabled); @@ -65,10 +66,7 @@ void MainWindow::open(const QUrl &docLocation) { if (docLocation.isLocalFile()) { m_document->load(docLocation.toLocalFile()); - const auto documentTitle = m_document->metaData(QPdfDocument::MetaDataField::Title).toString(); - setWindowTitle(!documentTitle.isEmpty() ? documentTitle : QStringLiteral("PDF Viewer")); pageSelected(0); - m_pageSelector->setMaximum(m_document->pageCount() - 1); } else { const QString message = tr("%1 is not a valid local file").arg(docLocation.toString()); qCDebug(lcExample).noquote() << message; @@ -91,6 +89,11 @@ void MainWindow::pageSelected(int page) { auto nav = ui->pdfView->pageNavigator(); nav->jump(page, {}, nav->currentZoom()); + const auto documentTitle = m_document->metaData(QPdfDocument::MetaDataField::Title).toString(); + setWindowTitle(!documentTitle.isEmpty() ? documentTitle : QStringLiteral("PDF Viewer")); + setWindowTitle(tr("%1: page %2 (%3 of %4)") + .arg(documentTitle.isEmpty() ? u"PDF Viewer"_qs : documentTitle, + m_pageSelector->text(), QString::number(page + 1), QString::number(m_document->pageCount()))); } void MainWindow::on_actionOpen_triggered() diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h index 958e11061..2827fb2b6 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.h +++ b/examples/pdfwidgets/pdfviewer/mainwindow.h @@ -16,6 +16,7 @@ class MainWindow; class QFileDialog; class QPdfDocument; +class QPdfPageSelector; class QPdfView; class QSpinBox; QT_END_NAMESPACE @@ -53,7 +54,7 @@ private slots: private: Ui::MainWindow *ui; ZoomSelector *m_zoomSelector; - QSpinBox *m_pageSelector; + QPdfPageSelector *m_pageSelector; QFileDialog *m_fileDialog = nullptr; QPdfDocument *m_document; diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp index 268389f4a..a6aed4bfe 100644 --- a/src/pdf/qpdfdocument.cpp +++ b/src/pdf/qpdfdocument.cpp @@ -783,6 +783,8 @@ QAbstractListModel *QPdfDocument::pageModel() If the document does not have custom page numbering, this function returns \c {page + 1}. + + \sa pageIndexForLabel() */ QString QPdfDocument::pageLabel(int page) { @@ -797,6 +799,21 @@ QString QPdfDocument::pageLabel(int page) } /*! + Returns the index of the page that has the \a label, or \c -1 if not found. + + \sa pageLabel() +*/ +int QPdfDocument::pageIndexForLabel(const QString &label) +{ + const auto trimmed = label.trimmed(); + for (int i = 0; i < d->pageCount; ++i) { + if (pageLabel(i) == trimmed) + return i; + } + return -1; +} + +/*! Renders the \a page into a QImage of size \a imageSize according to the provided \a renderOptions. diff --git a/src/pdf/qpdfdocument.h b/src/pdf/qpdfdocument.h index 5f55ed29c..8355246ae 100644 --- a/src/pdf/qpdfdocument.h +++ b/src/pdf/qpdfdocument.h @@ -89,6 +89,7 @@ public: Q_INVOKABLE QSizeF pagePointSize(int page) const; Q_INVOKABLE QString pageLabel(int page); + Q_INVOKABLE int pageIndexForLabel(const QString &label); QAbstractListModel *pageModel(); diff --git a/src/pdfwidgets/CMakeLists.txt b/src/pdfwidgets/CMakeLists.txt index d374315e3..592409b66 100644 --- a/src/pdfwidgets/CMakeLists.txt +++ b/src/pdfwidgets/CMakeLists.txt @@ -5,6 +5,7 @@ find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Widgets) qt_internal_add_module(PdfWidgets SOURCES + qpdfpageselector.cpp qpdfpageselector.h qpdfpageselector_p.h qpdfview.cpp qpdfview.h qpdfview_p.h qtpdfwidgetsglobal.h LIBRARIES diff --git a/src/pdfwidgets/qpdfpageselector.cpp b/src/pdfwidgets/qpdfpageselector.cpp new file mode 100644 index 000000000..72ab28355 --- /dev/null +++ b/src/pdfwidgets/qpdfpageselector.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qpdfpageselector.h" +#include "qpdfpageselector_p.h" + +#include <QPdfDocument> + +QT_BEGIN_NAMESPACE + +QPdfPageSelectorPrivate::QPdfPageSelectorPrivate(QPdfPageSelector *q) + : q_ptr(q) +{ +} + +void QPdfPageSelectorPrivate::documentStatusChanged() +{ + Q_Q(QPdfPageSelector); + if (!document.isNull() && document->status() == QPdfDocument::Status::Ready) { + q->setMaximum(document->pageCount()); + q->setValue(0); + } +} + +/*! + \class QPdfPageSelector + \inmodule QtPdf + \brief A QSpinBox for selecting a PDF page. + + QPdfPageSelector is a QSpinBox specialized for selecting a page label + from a QPdfDocument. + + \sa QPdfDocument::pageLabel() +*/ + +/*! + Constructs a PDF page selector with parent widget \a parent. +*/ +QPdfPageSelector::QPdfPageSelector(QWidget *parent) + : QSpinBox(parent) + , d_ptr(new QPdfPageSelectorPrivate(this)) +{ +} + +/*! + Destroys the page selector. +*/ +QPdfPageSelector::~QPdfPageSelector() +{ +} + +/*! + \property QPdfPageSelector::document + + This property holds the document to be viewed. +*/ +void QPdfPageSelector::setDocument(QPdfDocument *document) +{ + Q_D(QPdfPageSelector); + + if (d->document == document) + return; + + if (d->document) + disconnect(d->documentStatusChangedConnection); + + d->document = document; + emit documentChanged(d->document); + + if (d->document) + d->documentStatusChangedConnection = + connect(d->document.data(), &QPdfDocument::statusChanged, this, + [d](){ d->documentStatusChanged(); }); + + d->documentStatusChanged(); +} + +QPdfDocument *QPdfPageSelector::document() const +{ + Q_D(const QPdfPageSelector); + + return d->document; +} + +int QPdfPageSelector::valueFromText(const QString &text) const +{ + Q_D(const QPdfPageSelector); + if (d->document.isNull()) + return 0; + + return d->document->pageIndexForLabel(text); +} + +QString QPdfPageSelector::textFromValue(int value) const +{ + Q_D(const QPdfPageSelector); + if (d->document.isNull()) + return {}; + + return d->document->pageLabel(value); +} + +QT_END_NAMESPACE + +#include "moc_qpdfpageselector.cpp" diff --git a/src/pdfwidgets/qpdfpageselector.h b/src/pdfwidgets/qpdfpageselector.h new file mode 100644 index 000000000..bc2e352f7 --- /dev/null +++ b/src/pdfwidgets/qpdfpageselector.h @@ -0,0 +1,44 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QPDFPAGESELECTOR_H +#define QPDFPAGESELECTOR_H + +#include <QtPdfWidgets/qtpdfwidgetsglobal.h> +#include <QtWidgets/qspinbox.h> + +QT_BEGIN_NAMESPACE + +class QPdfDocument; +class QPdfPageNavigator; +class QPdfPageSelectorPrivate; + +class Q_PDF_WIDGETS_EXPORT QPdfPageSelector : public QSpinBox +{ + Q_OBJECT + + Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged) + +public: + QPdfPageSelector() : QPdfPageSelector(nullptr) {} + explicit QPdfPageSelector(QWidget *parent); + ~QPdfPageSelector(); + + void setDocument(QPdfDocument *document); + QPdfDocument *document() const; + +Q_SIGNALS: + void documentChanged(QPdfDocument *document); + +protected: + int valueFromText(const QString &text) const override; + QString textFromValue(int value) const override; + +private: + Q_DECLARE_PRIVATE(QPdfPageSelector) + QScopedPointer<QPdfPageSelectorPrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QPDFPAGESELECTOR_H diff --git a/src/pdfwidgets/qpdfpageselector_p.h b/src/pdfwidgets/qpdfpageselector_p.h new file mode 100644 index 000000000..b2cd6ecf7 --- /dev/null +++ b/src/pdfwidgets/qpdfpageselector_p.h @@ -0,0 +1,42 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QPDFPAGESELECTOR_P_H +#define QPDFPAGESELECTOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qpdfpageselector.h" + +#include <QPointer> + +QT_BEGIN_NAMESPACE + +class QPdfPageRenderer; + +class QPdfPageSelectorPrivate +{ + Q_DECLARE_PUBLIC(QPdfPageSelector) + +public: + QPdfPageSelectorPrivate(QPdfPageSelector *q); + + void documentStatusChanged(); + + QPdfPageSelector *q_ptr; + QPointer<QPdfDocument> document; + QMetaObject::Connection documentStatusChangedConnection; +}; + +QT_END_NAMESPACE + +#endif // QPDFPAGESELECTOR_P_H |