From 43cebeadbe8d0550aeee4aa35f3c93a9e7e14a34 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 24 Jan 2017 11:27:17 +0100 Subject: install the pdfviewer example; provide examples subdirs .pro files Actually moving the files is unfortunately necessary because of a rule about having the source directory structure match the intended installation directory structure. It was intended to differentiate widget examples from future QtQuick examples, but now that distiction is being unfortunately lost in order to keep the directory structure as shallow as it can still be, after having to comply with the first rule. Change-Id: I831227d2be3c8f5cab55a98a531e16bcb3aa0303 Reviewed-by: Oswald Buddenhagen --- examples/examples.pro | 2 + examples/pdf/pdf.pro | 2 + examples/pdf/pdfviewer/images/busy.png | Bin 0 -> 172 bytes examples/pdf/pdfviewer/images/fileopen.png | Bin 0 -> 1771 bytes examples/pdf/pdfviewer/images/go-next-24.png | Bin 0 -> 782 bytes examples/pdf/pdfviewer/images/go-previous-24.png | Bin 0 -> 797 bytes examples/pdf/pdfviewer/images/zoom-in-24.png | Bin 0 -> 1302 bytes examples/pdf/pdfviewer/images/zoom-in-32.png | Bin 0 -> 1873 bytes examples/pdf/pdfviewer/images/zoom-out-24.png | Bin 0 -> 1247 bytes examples/pdf/pdfviewer/images/zoom-out-32.png | Bin 0 -> 1749 bytes examples/pdf/pdfviewer/main.cpp | 51 ++++++ examples/pdf/pdfviewer/mainwindow.cpp | 170 ++++++++++++++++++ examples/pdf/pdfviewer/mainwindow.h | 89 ++++++++++ examples/pdf/pdfviewer/mainwindow.ui | 173 +++++++++++++++++++ examples/pdf/pdfviewer/pagerenderer.cpp | 105 +++++++++++ examples/pdf/pdfviewer/pagerenderer.h | 80 +++++++++ examples/pdf/pdfviewer/pdfviewer.pro | 21 +++ examples/pdf/pdfviewer/resources.qrc | 12 ++ examples/pdf/pdfviewer/sequentialpagewidget.cpp | 192 +++++++++++++++++++++ examples/pdf/pdfviewer/sequentialpagewidget.h | 96 +++++++++++ examples/widgets/pdfviewer/images/busy.png | Bin 172 -> 0 bytes examples/widgets/pdfviewer/images/fileopen.png | Bin 1771 -> 0 bytes examples/widgets/pdfviewer/images/go-next-24.png | Bin 782 -> 0 bytes .../widgets/pdfviewer/images/go-previous-24.png | Bin 797 -> 0 bytes examples/widgets/pdfviewer/images/zoom-in-24.png | Bin 1302 -> 0 bytes examples/widgets/pdfviewer/images/zoom-in-32.png | Bin 1873 -> 0 bytes examples/widgets/pdfviewer/images/zoom-out-24.png | Bin 1247 -> 0 bytes examples/widgets/pdfviewer/images/zoom-out-32.png | Bin 1749 -> 0 bytes examples/widgets/pdfviewer/main.cpp | 51 ------ examples/widgets/pdfviewer/mainwindow.cpp | 170 ------------------ examples/widgets/pdfviewer/mainwindow.h | 89 ---------- examples/widgets/pdfviewer/mainwindow.ui | 173 ------------------- examples/widgets/pdfviewer/pagerenderer.cpp | 105 ----------- examples/widgets/pdfviewer/pagerenderer.h | 80 --------- examples/widgets/pdfviewer/pdfviewer.pro | 17 -- examples/widgets/pdfviewer/resources.qrc | 12 -- .../widgets/pdfviewer/sequentialpagewidget.cpp | 192 --------------------- examples/widgets/pdfviewer/sequentialpagewidget.h | 96 ----------- 38 files changed, 993 insertions(+), 985 deletions(-) create mode 100644 examples/examples.pro create mode 100644 examples/pdf/pdf.pro create mode 100644 examples/pdf/pdfviewer/images/busy.png create mode 100644 examples/pdf/pdfviewer/images/fileopen.png create mode 100644 examples/pdf/pdfviewer/images/go-next-24.png create mode 100644 examples/pdf/pdfviewer/images/go-previous-24.png create mode 100644 examples/pdf/pdfviewer/images/zoom-in-24.png create mode 100644 examples/pdf/pdfviewer/images/zoom-in-32.png create mode 100644 examples/pdf/pdfviewer/images/zoom-out-24.png create mode 100644 examples/pdf/pdfviewer/images/zoom-out-32.png create mode 100644 examples/pdf/pdfviewer/main.cpp create mode 100644 examples/pdf/pdfviewer/mainwindow.cpp create mode 100644 examples/pdf/pdfviewer/mainwindow.h create mode 100644 examples/pdf/pdfviewer/mainwindow.ui create mode 100644 examples/pdf/pdfviewer/pagerenderer.cpp create mode 100644 examples/pdf/pdfviewer/pagerenderer.h create mode 100644 examples/pdf/pdfviewer/pdfviewer.pro create mode 100644 examples/pdf/pdfviewer/resources.qrc create mode 100644 examples/pdf/pdfviewer/sequentialpagewidget.cpp create mode 100644 examples/pdf/pdfviewer/sequentialpagewidget.h delete mode 100644 examples/widgets/pdfviewer/images/busy.png delete mode 100644 examples/widgets/pdfviewer/images/fileopen.png delete mode 100644 examples/widgets/pdfviewer/images/go-next-24.png delete mode 100644 examples/widgets/pdfviewer/images/go-previous-24.png delete mode 100644 examples/widgets/pdfviewer/images/zoom-in-24.png delete mode 100644 examples/widgets/pdfviewer/images/zoom-in-32.png delete mode 100644 examples/widgets/pdfviewer/images/zoom-out-24.png delete mode 100644 examples/widgets/pdfviewer/images/zoom-out-32.png delete mode 100644 examples/widgets/pdfviewer/main.cpp delete mode 100644 examples/widgets/pdfviewer/mainwindow.cpp delete mode 100644 examples/widgets/pdfviewer/mainwindow.h delete mode 100644 examples/widgets/pdfviewer/mainwindow.ui delete mode 100644 examples/widgets/pdfviewer/pagerenderer.cpp delete mode 100644 examples/widgets/pdfviewer/pagerenderer.h delete mode 100644 examples/widgets/pdfviewer/pdfviewer.pro delete mode 100644 examples/widgets/pdfviewer/resources.qrc delete mode 100644 examples/widgets/pdfviewer/sequentialpagewidget.cpp delete mode 100644 examples/widgets/pdfviewer/sequentialpagewidget.h diff --git a/examples/examples.pro b/examples/examples.pro new file mode 100644 index 0000000..c3b9cb3 --- /dev/null +++ b/examples/examples.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += pdf diff --git a/examples/pdf/pdf.pro b/examples/pdf/pdf.pro new file mode 100644 index 0000000..a12dc5b --- /dev/null +++ b/examples/pdf/pdf.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += pdfviewer diff --git a/examples/pdf/pdfviewer/images/busy.png b/examples/pdf/pdfviewer/images/busy.png new file mode 100644 index 0000000..69056c4 Binary files /dev/null and b/examples/pdf/pdfviewer/images/busy.png differ diff --git a/examples/pdf/pdfviewer/images/fileopen.png b/examples/pdf/pdfviewer/images/fileopen.png new file mode 100644 index 0000000..33e0d63 Binary files /dev/null and b/examples/pdf/pdfviewer/images/fileopen.png differ diff --git a/examples/pdf/pdfviewer/images/go-next-24.png b/examples/pdf/pdfviewer/images/go-next-24.png new file mode 100644 index 0000000..9a55ef3 Binary files /dev/null and b/examples/pdf/pdfviewer/images/go-next-24.png differ diff --git a/examples/pdf/pdfviewer/images/go-previous-24.png b/examples/pdf/pdfviewer/images/go-previous-24.png new file mode 100644 index 0000000..2ea769e Binary files /dev/null and b/examples/pdf/pdfviewer/images/go-previous-24.png differ diff --git a/examples/pdf/pdfviewer/images/zoom-in-24.png b/examples/pdf/pdfviewer/images/zoom-in-24.png new file mode 100644 index 0000000..d29b142 Binary files /dev/null and b/examples/pdf/pdfviewer/images/zoom-in-24.png differ diff --git a/examples/pdf/pdfviewer/images/zoom-in-32.png b/examples/pdf/pdfviewer/images/zoom-in-32.png new file mode 100644 index 0000000..34d70af Binary files /dev/null and b/examples/pdf/pdfviewer/images/zoom-in-32.png differ diff --git a/examples/pdf/pdfviewer/images/zoom-out-24.png b/examples/pdf/pdfviewer/images/zoom-out-24.png new file mode 100644 index 0000000..1970347 Binary files /dev/null and b/examples/pdf/pdfviewer/images/zoom-out-24.png differ diff --git a/examples/pdf/pdfviewer/images/zoom-out-32.png b/examples/pdf/pdfviewer/images/zoom-out-32.png new file mode 100644 index 0000000..b832206 Binary files /dev/null and b/examples/pdf/pdfviewer/images/zoom-out-32.png differ diff --git a/examples/pdf/pdfviewer/main.cpp b/examples/pdf/pdfviewer/main.cpp new file mode 100644 index 0000000..20fa6f8 --- /dev/null +++ b/examples/pdf/pdfviewer/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + QStringList args = a.arguments(); + w.show(); + if (args.length() > 1) + w.open(QUrl::fromLocalFile(args[1])); + + return a.exec(); +} diff --git a/examples/pdf/pdfviewer/mainwindow.cpp b/examples/pdf/pdfviewer/mainwindow.cpp new file mode 100644 index 0000000..d865a8b --- /dev/null +++ b/examples/pdf/pdfviewer/mainwindow.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include "sequentialpagewidget.h" + +#include +#include +#include +#include +#include +#include + +const qreal zoomMultiplier = qSqrt(2.0); + +Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer") + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_pageWidget(new SequentialPageWidget(this)) + , m_zoomEdit(new QLineEdit(this)) + , m_pageEdit(new QLineEdit(this)) + , m_document(new QPdfDocument(this)) +{ + ui->setupUi(this); + ui->scrollArea->setWidget(m_pageWidget); + m_zoomEdit->setMaximumWidth(50); + m_zoomEdit->setAlignment(Qt::AlignHCenter); + ui->mainToolBar->insertWidget(ui->actionZoom_In, m_zoomEdit); + m_pageEdit->setMaximumWidth(50); + m_pageEdit->setAlignment(Qt::AlignHCenter); + ui->mainToolBar->insertWidget(ui->actionGo, m_pageEdit); + connect(m_pageWidget, SIGNAL(showingPageRange(int,int)), + this, SLOT(showingPageRange(int,int)), Qt::QueuedConnection); + connect(m_pageWidget, SIGNAL(zoomChanged(qreal)), + this, SLOT(zoomChanged(qreal))); + connect(m_zoomEdit, SIGNAL(returnPressed()), this, SLOT(zoomEdited())); + connect(m_pageEdit, SIGNAL(returnPressed()), this, SLOT(on_actionGo_triggered())); + + QScroller::grabGesture(ui->scrollArea); + + m_pageWidget->setDocument(m_document); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::open(const QUrl &docLocation) +{ + if (docLocation.isLocalFile()) { + m_document->load(docLocation.toLocalFile()); + } else { + qCDebug(lcExample) << docLocation << "is not a valid local file"; + QMessageBox::critical(this, tr("Failed to open"), tr("%1 is not a valid local file").arg(docLocation.toString())); + } + qCDebug(lcExample) << docLocation; + ui->scrollArea->ensureVisible(0, 0, 0, 0); +} + +void MainWindow::showingPageRange(int start, int end) +{ + ui->statusBar->clearMessage(); + if (start == end) + ui->statusBar->showMessage(tr("showing page %1").arg(start)); + else + ui->statusBar->showMessage(tr("showing pages %1 to %2").arg(start).arg(end)); + m_pageEdit->setText(QString::number(end)); +} + +void MainWindow::zoomChanged(qreal factor) +{ + m_zoomEdit->setText(tr("%1%").arg(factor * 100., 0, 'f', 0)); +} + +void MainWindow::zoomEdited() +{ + bool ok = false; + qreal factor = m_zoomEdit->text().remove(QChar('%')).toDouble(&ok); + if (ok) + m_pageWidget->setZoom(factor / 100.); +} + +void MainWindow::on_actionOpen_triggered() +{ + QUrl toOpen = QFileDialog::getOpenFileUrl(this, tr("Choose a PDF"), QUrl(), "Portable Documents (*.pdf)"); + if (toOpen.isValid()) + open(toOpen); +} + +void MainWindow::on_actionQuit_triggered() +{ + QApplication::quit(); +} + +void MainWindow::on_actionAbout_triggered() +{ + QMessageBox::about(this, tr("About PdfViewer"), + tr("An example using QPdfDocument")); +} + +void MainWindow::on_actionAbout_Qt_triggered() +{ + QMessageBox::aboutQt(this); +} + +void MainWindow::on_actionZoom_In_triggered() +{ + m_pageWidget->setZoom(m_pageWidget->zoom() * zoomMultiplier); +} + +void MainWindow::on_actionZoom_Out_triggered() +{ + m_pageWidget->setZoom(m_pageWidget->zoom() / zoomMultiplier); +} + +void MainWindow::on_actionGo_triggered() +{ + bool ok = false; + int page = m_pageEdit->text().toInt(&ok); + if (!ok) return; + ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(page)); +} + +void MainWindow::on_actionPrevious_Page_triggered() +{ + ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(m_pageWidget->topPageShowing() - 1)); +} + +void MainWindow::on_actionNext_Page_triggered() +{ + ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(m_pageWidget->bottomPageShowing() + 1)); +} diff --git a/examples/pdf/pdfviewer/mainwindow.h b/examples/pdf/pdfviewer/mainwindow.h new file mode 100644 index 0000000..dedc812 --- /dev/null +++ b/examples/pdf/pdfviewer/mainwindow.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +namespace Ui { +class MainWindow; +} + +class QLineEdit; +class QPdfDocument; +class SequentialPageWidget; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +public slots: + void open(const QUrl &docLocation); + +private slots: + void showingPageRange(int start, int end); + void zoomChanged(qreal factor); + void zoomEdited(); + + // action handlers + void on_actionOpen_triggered(); + void on_actionQuit_triggered(); + void on_actionAbout_triggered(); + void on_actionAbout_Qt_triggered(); + void on_actionZoom_In_triggered(); + void on_actionZoom_Out_triggered(); + void on_actionGo_triggered(); + void on_actionPrevious_Page_triggered(); + void on_actionNext_Page_triggered(); + +private: + Ui::MainWindow *ui; + SequentialPageWidget *m_pageWidget; + QLineEdit *m_zoomEdit; + QLineEdit *m_pageEdit; + + QPdfDocument *m_document; +}; + +#endif // MAINWINDOW_H diff --git a/examples/pdf/pdfviewer/mainwindow.ui b/examples/pdf/pdfviewer/mainwindow.ui new file mode 100644 index 0000000..7070619 --- /dev/null +++ b/examples/pdf/pdfviewer/mainwindow.ui @@ -0,0 +1,173 @@ + + + MainWindow + + + + 0 + 0 + 400 + 300 + + + + MainWindow + + + + + + + true + + + + + 0 + 0 + 380 + 200 + + + + + + + + + + + + 0 + 0 + 400 + 19 + + + + + File + + + + + + + Help + + + + + + + View + + + + + + + + + + + + + TopToolBarArea + + + false + + + + + + + + + + + + + :/icons/images/fileopen.png:/icons/images/fileopen.png + + + Open... + + + Ctrl+O + + + + + Quit + + + Ctrl+Q + + + + + About + + + + + About Qt + + + + + + :/icons/images/zoom-in-24.png:/icons/images/zoom-in-24.png + + + Zoom In + + + Ctrl+= + + + + + + :/icons/images/zoom-out-24.png:/icons/images/zoom-out-24.png + + + Zoom Out + + + Ctrl+- + + + + + Go + + + Go to Page + + + + + Previous Page + + + PgUp + + + + + Next Page + + + PgDown + + + + + + + + + diff --git a/examples/pdf/pdfviewer/pagerenderer.cpp b/examples/pdf/pdfviewer/pagerenderer.cpp new file mode 100644 index 0000000..c8f2456 --- /dev/null +++ b/examples/pdf/pdfviewer/pagerenderer.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pagerenderer.h" + +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +PageRenderer::PageRenderer(QObject *parent) + : QThread(parent) + , m_document(nullptr) + , m_page(0) + , m_zoom(1.) + , m_minRenderTime(1000000000.) + , m_maxRenderTime(0.) + , m_totalRenderTime(0.) + , m_totalPagesRendered(0) +{ +} + +void PageRenderer::setDocument(QPdfDocument *document) +{ + m_document = document; +} + +void PageRenderer::requestPage(int page, qreal zoom, Priority priority) +{ + // TODO maybe queue up the requests + m_page = page; + m_zoom = zoom; + start(priority); +} + +void PageRenderer::run() +{ + renderPage(m_page, m_zoom); +} + +void PageRenderer::renderPage(int page, qreal zoom) +{ + if (!m_document || m_document->status() != QPdfDocument::Ready) + return; + + const QSizeF size = m_document->pageSize(page) * m_zoom; + + QElapsedTimer timer; + timer.start(); + + const QImage &img = m_document->render(page, size); + + const qreal secs = timer.nsecsElapsed() / 1000000000.0; + if (secs < m_minRenderTime) + m_minRenderTime = secs; + + if (secs > m_maxRenderTime) + m_maxRenderTime = secs; + + m_totalRenderTime += secs; + ++m_totalPagesRendered; + + emit pageReady(page, zoom, img); + + qCDebug(lcExample) << "page" << page << "zoom" << m_zoom << "size" << size << "in" << secs << + "secs; min" << m_minRenderTime << + "avg" << m_totalRenderTime / m_totalPagesRendered << + "max" << m_maxRenderTime; +} diff --git a/examples/pdf/pdfviewer/pagerenderer.h b/examples/pdf/pdfviewer/pagerenderer.h new file mode 100644 index 0000000..5feccaa --- /dev/null +++ b/examples/pdf/pdfviewer/pagerenderer.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PAGECACHE_H +#define PAGECACHE_H + +#include +#include + +class QPdfDocument; + +class PageRenderer : public QThread +{ + Q_OBJECT + +public: + explicit PageRenderer(QObject *parent = nullptr); + +public slots: + void setDocument(QPdfDocument *document); + + void requestPage(int page, qreal zoom, Priority priority = QThread::NormalPriority); + +signals: + void pageReady(int page, qreal zoom, QImage image); + +protected: + void run() override; + +private: + void renderPage(int page, qreal zoom); + +private: + QPdfDocument *m_document; + + // current request only + int m_page; + qreal m_zoom; + + // performance statistics + qreal m_minRenderTime; + qreal m_maxRenderTime; + qreal m_totalRenderTime; + int m_totalPagesRendered; +}; + +#endif // PAGECACHE_H diff --git a/examples/pdf/pdfviewer/pdfviewer.pro b/examples/pdf/pdfviewer/pdfviewer.pro new file mode 100644 index 0000000..10cacce --- /dev/null +++ b/examples/pdf/pdfviewer/pdfviewer.pro @@ -0,0 +1,21 @@ +QT += core gui widgets pdf +TARGET = pdfviewer +TEMPLATE = app + +SOURCES += main.cpp\ + mainwindow.cpp \ + sequentialpagewidget.cpp \ + pagerenderer.cpp + +HEADERS += mainwindow.h \ + sequentialpagewidget.h \ + pagerenderer.h + +FORMS += mainwindow.ui + +RESOURCES += \ + resources.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/pdf/pdfviewer +INSTALLS += target + diff --git a/examples/pdf/pdfviewer/resources.qrc b/examples/pdf/pdfviewer/resources.qrc new file mode 100644 index 0000000..02d9655 --- /dev/null +++ b/examples/pdf/pdfviewer/resources.qrc @@ -0,0 +1,12 @@ + + + images/fileopen.png + images/go-next-24.png + images/go-previous-24.png + images/zoom-in-24.png + images/zoom-in-32.png + images/zoom-out-24.png + images/zoom-out-32.png + images/busy.png + + diff --git a/examples/pdf/pdfviewer/sequentialpagewidget.cpp b/examples/pdf/pdfviewer/sequentialpagewidget.cpp new file mode 100644 index 0000000..904bc17 --- /dev/null +++ b/examples/pdf/pdfviewer/sequentialpagewidget.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sequentialpagewidget.h" +#include "pagerenderer.h" +#include +#include +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +SequentialPageWidget::SequentialPageWidget(QWidget *parent) + : QWidget(parent) + , m_pageCacheLimit(20) + , m_pageRenderer(new PageRenderer()) + , m_background(Qt::darkGray) + , m_placeholderIcon(":icons/images/busy.png") + , m_placeholderBackground(Qt::white) + , m_pageSpacing(3) + , m_topPageShowing(0) + , m_zoom(1.) + , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) + , m_document(nullptr) +{ + connect(m_pageRenderer, SIGNAL(pageReady(int, qreal, QImage)), this, SLOT(pageLoaded(int, qreal, QImage)), Qt::QueuedConnection); + grabGesture(Qt::SwipeGesture); +} + +SequentialPageWidget::~SequentialPageWidget() +{ + delete m_pageRenderer; +} + +void SequentialPageWidget::setDocument(QPdfDocument *document) +{ + m_pageRenderer->setDocument(document); + + m_document = document; + connect(m_document, &QPdfDocument::statusChanged, this, &SequentialPageWidget::documentStatusChanged); + + documentStatusChanged(); +} + +void SequentialPageWidget::setZoom(qreal factor) +{ + m_zoom = factor; + emit zoomChanged(factor); + invalidate(); +} + +QSizeF SequentialPageWidget::pageSize(int page) +{ +// if (!m_pageSizes.length() <= page) +// return QSizeF(); + return m_pageSizes[page] * m_screenResolution * m_zoom; +} + +void SequentialPageWidget::invalidate() +{ + QSizeF totalSize(0, m_pageSpacing); + for (int page = 0; page < pageCount(); ++page) { + QSizeF size = pageSize(page); + totalSize.setHeight(totalSize.height() + size.height()); + if (size.width() > totalSize.width()) + totalSize.setWidth(size.width()); + } + m_totalSize = totalSize.toSize(); + setMinimumSize(m_totalSize); + emit zoomChanged(m_zoom); + qCDebug(lcExample) << "total size" << m_totalSize; + m_pageCache.clear(); + update(); +} + +void SequentialPageWidget::documentStatusChanged() +{ + m_pageSizes.clear(); + m_topPageShowing = 0; + + if (m_document->status() == QPdfDocument::Ready) { + for (int page = 0; page < m_document->pageCount(); ++page) + m_pageSizes.append(m_document->pageSize(page)); + } + + invalidate(); +} + +void SequentialPageWidget::pageLoaded(int page, qreal zoom, QImage image) +{ + Q_UNUSED(zoom) + if (m_cachedPagesLRU.length() > m_pageCacheLimit) + m_pageCache.remove(m_cachedPagesLRU.takeFirst()); + m_pageCache.insert(page, image); + m_cachedPagesLRU.append(page); + update(); +} + +int SequentialPageWidget::pageCount() +{ + return m_pageSizes.count(); +} + +void SequentialPageWidget::paintEvent(QPaintEvent * event) +{ + QPainter painter(this); + painter.fillRect(event->rect(), m_background); + + if (m_pageSizes.isEmpty()) + return; + + // Find the first page that needs to be rendered + int page = 0; + int y = 0; + while (page < pageCount()) { + QSizeF size = pageSize(page); + int height = size.toSize().height(); + if (y + height >= event->rect().top()) + break; + y += height + m_pageSpacing; + ++page; + } + y += m_pageSpacing; + m_topPageShowing = page; + + // Actually render pages + while (y < event->rect().bottom() && page < pageCount()) { + QSizeF size = pageSize(page); + if (m_pageCache.contains(page)) { + const QImage &img = m_pageCache[page]; + painter.fillRect((width() - img.width()) / 2, y, size.width(), size.height(), Qt::white); + painter.drawImage((width() - img.width()) / 2, y, img); + } else { + painter.fillRect((width() - size.width()) / 2, y, size.width(), size.height(), m_placeholderBackground); + painter.drawPixmap((size.width() - m_placeholderIcon.width()) / 2, + (size.height() - m_placeholderIcon.height()) / 2, m_placeholderIcon); + m_pageRenderer->requestPage(page, m_screenResolution * m_zoom); + } + y += size.height() + m_pageSpacing; + ++page; + } + m_bottomPageShowing = page - 1; + emit showingPageRange(m_topPageShowing, m_bottomPageShowing); +} + +qreal SequentialPageWidget::yForPage(int endPage) +{ + // TODO maybe put this loop into a page iterator class + int y = m_pageSpacing; + for (int page = 0; page < pageCount() && page < endPage; ++page) { + QSizeF size = pageSize(page); + int height = size.toSize().height(); + y += height + m_pageSpacing; + } + return y; +} diff --git a/examples/pdf/pdfviewer/sequentialpagewidget.h b/examples/pdf/pdfviewer/sequentialpagewidget.h new file mode 100644 index 0000000..85f3571 --- /dev/null +++ b/examples/pdf/pdfviewer/sequentialpagewidget.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPDF module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SEQUENTIALPAGEWIDGET_H +#define SEQUENTIALPAGEWIDGET_H + +#include + +class QPdfDocument; +class PageRenderer; + +class SequentialPageWidget : public QWidget +{ + Q_OBJECT +public: + explicit SequentialPageWidget(QWidget *parent = 0); + ~SequentialPageWidget(); + + void paintEvent(QPaintEvent * event); + qreal zoom() { return m_zoom; } + qreal yForPage(int page); + int topPageShowing() { return m_topPageShowing; } + int bottomPageShowing() { return m_bottomPageShowing; } + + void setDocument(QPdfDocument *document); + +public slots: + void setZoom(qreal factor); + void invalidate(); + +signals: + void showingPageRange(int start, int end); + void zoomChanged(qreal factor); + +private slots: + void documentStatusChanged(); + void pageLoaded(int page, qreal zoom, QImage image); + +private: + int pageCount(); + QSizeF pageSize(int page); + void render(int page); + +private: + QHash m_pageCache; + QVector m_cachedPagesLRU; + int m_pageCacheLimit; + QVector m_pageSizes; + PageRenderer *m_pageRenderer; + QBrush m_background; + QPixmap m_placeholderIcon; + QBrush m_placeholderBackground; + int m_pageSpacing; + int m_topPageShowing; + int m_bottomPageShowing; + QSize m_totalSize; + qreal m_zoom; + qreal m_screenResolution; // pixels per point + + QPdfDocument *m_document; +}; + +#endif // SEQUENTIALPAGEWIDGET_H diff --git a/examples/widgets/pdfviewer/images/busy.png b/examples/widgets/pdfviewer/images/busy.png deleted file mode 100644 index 69056c4..0000000 Binary files a/examples/widgets/pdfviewer/images/busy.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/fileopen.png b/examples/widgets/pdfviewer/images/fileopen.png deleted file mode 100644 index 33e0d63..0000000 Binary files a/examples/widgets/pdfviewer/images/fileopen.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/go-next-24.png b/examples/widgets/pdfviewer/images/go-next-24.png deleted file mode 100644 index 9a55ef3..0000000 Binary files a/examples/widgets/pdfviewer/images/go-next-24.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/go-previous-24.png b/examples/widgets/pdfviewer/images/go-previous-24.png deleted file mode 100644 index 2ea769e..0000000 Binary files a/examples/widgets/pdfviewer/images/go-previous-24.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/zoom-in-24.png b/examples/widgets/pdfviewer/images/zoom-in-24.png deleted file mode 100644 index d29b142..0000000 Binary files a/examples/widgets/pdfviewer/images/zoom-in-24.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/zoom-in-32.png b/examples/widgets/pdfviewer/images/zoom-in-32.png deleted file mode 100644 index 34d70af..0000000 Binary files a/examples/widgets/pdfviewer/images/zoom-in-32.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/zoom-out-24.png b/examples/widgets/pdfviewer/images/zoom-out-24.png deleted file mode 100644 index 1970347..0000000 Binary files a/examples/widgets/pdfviewer/images/zoom-out-24.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/images/zoom-out-32.png b/examples/widgets/pdfviewer/images/zoom-out-32.png deleted file mode 100644 index b832206..0000000 Binary files a/examples/widgets/pdfviewer/images/zoom-out-32.png and /dev/null differ diff --git a/examples/widgets/pdfviewer/main.cpp b/examples/widgets/pdfviewer/main.cpp deleted file mode 100644 index 20fa6f8..0000000 --- a/examples/widgets/pdfviewer/main.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" -#include -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - QStringList args = a.arguments(); - w.show(); - if (args.length() > 1) - w.open(QUrl::fromLocalFile(args[1])); - - return a.exec(); -} diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp deleted file mode 100644 index d865a8b..0000000 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" -#include "ui_mainwindow.h" - -#include "sequentialpagewidget.h" - -#include -#include -#include -#include -#include -#include - -const qreal zoomMultiplier = qSqrt(2.0); - -Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer") - -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) - , m_pageWidget(new SequentialPageWidget(this)) - , m_zoomEdit(new QLineEdit(this)) - , m_pageEdit(new QLineEdit(this)) - , m_document(new QPdfDocument(this)) -{ - ui->setupUi(this); - ui->scrollArea->setWidget(m_pageWidget); - m_zoomEdit->setMaximumWidth(50); - m_zoomEdit->setAlignment(Qt::AlignHCenter); - ui->mainToolBar->insertWidget(ui->actionZoom_In, m_zoomEdit); - m_pageEdit->setMaximumWidth(50); - m_pageEdit->setAlignment(Qt::AlignHCenter); - ui->mainToolBar->insertWidget(ui->actionGo, m_pageEdit); - connect(m_pageWidget, SIGNAL(showingPageRange(int,int)), - this, SLOT(showingPageRange(int,int)), Qt::QueuedConnection); - connect(m_pageWidget, SIGNAL(zoomChanged(qreal)), - this, SLOT(zoomChanged(qreal))); - connect(m_zoomEdit, SIGNAL(returnPressed()), this, SLOT(zoomEdited())); - connect(m_pageEdit, SIGNAL(returnPressed()), this, SLOT(on_actionGo_triggered())); - - QScroller::grabGesture(ui->scrollArea); - - m_pageWidget->setDocument(m_document); -} - -MainWindow::~MainWindow() -{ - delete ui; -} - -void MainWindow::open(const QUrl &docLocation) -{ - if (docLocation.isLocalFile()) { - m_document->load(docLocation.toLocalFile()); - } else { - qCDebug(lcExample) << docLocation << "is not a valid local file"; - QMessageBox::critical(this, tr("Failed to open"), tr("%1 is not a valid local file").arg(docLocation.toString())); - } - qCDebug(lcExample) << docLocation; - ui->scrollArea->ensureVisible(0, 0, 0, 0); -} - -void MainWindow::showingPageRange(int start, int end) -{ - ui->statusBar->clearMessage(); - if (start == end) - ui->statusBar->showMessage(tr("showing page %1").arg(start)); - else - ui->statusBar->showMessage(tr("showing pages %1 to %2").arg(start).arg(end)); - m_pageEdit->setText(QString::number(end)); -} - -void MainWindow::zoomChanged(qreal factor) -{ - m_zoomEdit->setText(tr("%1%").arg(factor * 100., 0, 'f', 0)); -} - -void MainWindow::zoomEdited() -{ - bool ok = false; - qreal factor = m_zoomEdit->text().remove(QChar('%')).toDouble(&ok); - if (ok) - m_pageWidget->setZoom(factor / 100.); -} - -void MainWindow::on_actionOpen_triggered() -{ - QUrl toOpen = QFileDialog::getOpenFileUrl(this, tr("Choose a PDF"), QUrl(), "Portable Documents (*.pdf)"); - if (toOpen.isValid()) - open(toOpen); -} - -void MainWindow::on_actionQuit_triggered() -{ - QApplication::quit(); -} - -void MainWindow::on_actionAbout_triggered() -{ - QMessageBox::about(this, tr("About PdfViewer"), - tr("An example using QPdfDocument")); -} - -void MainWindow::on_actionAbout_Qt_triggered() -{ - QMessageBox::aboutQt(this); -} - -void MainWindow::on_actionZoom_In_triggered() -{ - m_pageWidget->setZoom(m_pageWidget->zoom() * zoomMultiplier); -} - -void MainWindow::on_actionZoom_Out_triggered() -{ - m_pageWidget->setZoom(m_pageWidget->zoom() / zoomMultiplier); -} - -void MainWindow::on_actionGo_triggered() -{ - bool ok = false; - int page = m_pageEdit->text().toInt(&ok); - if (!ok) return; - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(page)); -} - -void MainWindow::on_actionPrevious_Page_triggered() -{ - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(m_pageWidget->topPageShowing() - 1)); -} - -void MainWindow::on_actionNext_Page_triggered() -{ - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(m_pageWidget->bottomPageShowing() + 1)); -} diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h deleted file mode 100644 index dedc812..0000000 --- a/examples/widgets/pdfviewer/mainwindow.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(lcExample) - -namespace Ui { -class MainWindow; -} - -class QLineEdit; -class QPdfDocument; -class SequentialPageWidget; - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow(); - -public slots: - void open(const QUrl &docLocation); - -private slots: - void showingPageRange(int start, int end); - void zoomChanged(qreal factor); - void zoomEdited(); - - // action handlers - void on_actionOpen_triggered(); - void on_actionQuit_triggered(); - void on_actionAbout_triggered(); - void on_actionAbout_Qt_triggered(); - void on_actionZoom_In_triggered(); - void on_actionZoom_Out_triggered(); - void on_actionGo_triggered(); - void on_actionPrevious_Page_triggered(); - void on_actionNext_Page_triggered(); - -private: - Ui::MainWindow *ui; - SequentialPageWidget *m_pageWidget; - QLineEdit *m_zoomEdit; - QLineEdit *m_pageEdit; - - QPdfDocument *m_document; -}; - -#endif // MAINWINDOW_H diff --git a/examples/widgets/pdfviewer/mainwindow.ui b/examples/widgets/pdfviewer/mainwindow.ui deleted file mode 100644 index 7070619..0000000 --- a/examples/widgets/pdfviewer/mainwindow.ui +++ /dev/null @@ -1,173 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 400 - 300 - - - - MainWindow - - - - - - - true - - - - - 0 - 0 - 380 - 200 - - - - - - - - - - - - 0 - 0 - 400 - 19 - - - - - File - - - - - - - Help - - - - - - - View - - - - - - - - - - - - - TopToolBarArea - - - false - - - - - - - - - - - - - :/icons/images/fileopen.png:/icons/images/fileopen.png - - - Open... - - - Ctrl+O - - - - - Quit - - - Ctrl+Q - - - - - About - - - - - About Qt - - - - - - :/icons/images/zoom-in-24.png:/icons/images/zoom-in-24.png - - - Zoom In - - - Ctrl+= - - - - - - :/icons/images/zoom-out-24.png:/icons/images/zoom-out-24.png - - - Zoom Out - - - Ctrl+- - - - - - Go - - - Go to Page - - - - - Previous Page - - - PgUp - - - - - Next Page - - - PgDown - - - - - - - - - diff --git a/examples/widgets/pdfviewer/pagerenderer.cpp b/examples/widgets/pdfviewer/pagerenderer.cpp deleted file mode 100644 index c8f2456..0000000 --- a/examples/widgets/pdfviewer/pagerenderer.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "pagerenderer.h" - -#include -#include -#include -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(lcExample) - -PageRenderer::PageRenderer(QObject *parent) - : QThread(parent) - , m_document(nullptr) - , m_page(0) - , m_zoom(1.) - , m_minRenderTime(1000000000.) - , m_maxRenderTime(0.) - , m_totalRenderTime(0.) - , m_totalPagesRendered(0) -{ -} - -void PageRenderer::setDocument(QPdfDocument *document) -{ - m_document = document; -} - -void PageRenderer::requestPage(int page, qreal zoom, Priority priority) -{ - // TODO maybe queue up the requests - m_page = page; - m_zoom = zoom; - start(priority); -} - -void PageRenderer::run() -{ - renderPage(m_page, m_zoom); -} - -void PageRenderer::renderPage(int page, qreal zoom) -{ - if (!m_document || m_document->status() != QPdfDocument::Ready) - return; - - const QSizeF size = m_document->pageSize(page) * m_zoom; - - QElapsedTimer timer; - timer.start(); - - const QImage &img = m_document->render(page, size); - - const qreal secs = timer.nsecsElapsed() / 1000000000.0; - if (secs < m_minRenderTime) - m_minRenderTime = secs; - - if (secs > m_maxRenderTime) - m_maxRenderTime = secs; - - m_totalRenderTime += secs; - ++m_totalPagesRendered; - - emit pageReady(page, zoom, img); - - qCDebug(lcExample) << "page" << page << "zoom" << m_zoom << "size" << size << "in" << secs << - "secs; min" << m_minRenderTime << - "avg" << m_totalRenderTime / m_totalPagesRendered << - "max" << m_maxRenderTime; -} diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h deleted file mode 100644 index 5feccaa..0000000 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PAGECACHE_H -#define PAGECACHE_H - -#include -#include - -class QPdfDocument; - -class PageRenderer : public QThread -{ - Q_OBJECT - -public: - explicit PageRenderer(QObject *parent = nullptr); - -public slots: - void setDocument(QPdfDocument *document); - - void requestPage(int page, qreal zoom, Priority priority = QThread::NormalPriority); - -signals: - void pageReady(int page, qreal zoom, QImage image); - -protected: - void run() override; - -private: - void renderPage(int page, qreal zoom); - -private: - QPdfDocument *m_document; - - // current request only - int m_page; - qreal m_zoom; - - // performance statistics - qreal m_minRenderTime; - qreal m_maxRenderTime; - qreal m_totalRenderTime; - int m_totalPagesRendered; -}; - -#endif // PAGECACHE_H diff --git a/examples/widgets/pdfviewer/pdfviewer.pro b/examples/widgets/pdfviewer/pdfviewer.pro deleted file mode 100644 index e8269c4..0000000 --- a/examples/widgets/pdfviewer/pdfviewer.pro +++ /dev/null @@ -1,17 +0,0 @@ -QT += core gui widgets pdf -TARGET = pdfviewer -TEMPLATE = app - -SOURCES += main.cpp\ - mainwindow.cpp \ - sequentialpagewidget.cpp \ - pagerenderer.cpp - -HEADERS += mainwindow.h \ - sequentialpagewidget.h \ - pagerenderer.h - -FORMS += mainwindow.ui - -RESOURCES += \ - resources.qrc diff --git a/examples/widgets/pdfviewer/resources.qrc b/examples/widgets/pdfviewer/resources.qrc deleted file mode 100644 index 02d9655..0000000 --- a/examples/widgets/pdfviewer/resources.qrc +++ /dev/null @@ -1,12 +0,0 @@ - - - images/fileopen.png - images/go-next-24.png - images/go-previous-24.png - images/zoom-in-24.png - images/zoom-in-32.png - images/zoom-out-24.png - images/zoom-out-32.png - images/busy.png - - diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp deleted file mode 100644 index 904bc17..0000000 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "sequentialpagewidget.h" -#include "pagerenderer.h" -#include -#include -#include -#include -#include -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(lcExample) - -SequentialPageWidget::SequentialPageWidget(QWidget *parent) - : QWidget(parent) - , m_pageCacheLimit(20) - , m_pageRenderer(new PageRenderer()) - , m_background(Qt::darkGray) - , m_placeholderIcon(":icons/images/busy.png") - , m_placeholderBackground(Qt::white) - , m_pageSpacing(3) - , m_topPageShowing(0) - , m_zoom(1.) - , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) - , m_document(nullptr) -{ - connect(m_pageRenderer, SIGNAL(pageReady(int, qreal, QImage)), this, SLOT(pageLoaded(int, qreal, QImage)), Qt::QueuedConnection); - grabGesture(Qt::SwipeGesture); -} - -SequentialPageWidget::~SequentialPageWidget() -{ - delete m_pageRenderer; -} - -void SequentialPageWidget::setDocument(QPdfDocument *document) -{ - m_pageRenderer->setDocument(document); - - m_document = document; - connect(m_document, &QPdfDocument::statusChanged, this, &SequentialPageWidget::documentStatusChanged); - - documentStatusChanged(); -} - -void SequentialPageWidget::setZoom(qreal factor) -{ - m_zoom = factor; - emit zoomChanged(factor); - invalidate(); -} - -QSizeF SequentialPageWidget::pageSize(int page) -{ -// if (!m_pageSizes.length() <= page) -// return QSizeF(); - return m_pageSizes[page] * m_screenResolution * m_zoom; -} - -void SequentialPageWidget::invalidate() -{ - QSizeF totalSize(0, m_pageSpacing); - for (int page = 0; page < pageCount(); ++page) { - QSizeF size = pageSize(page); - totalSize.setHeight(totalSize.height() + size.height()); - if (size.width() > totalSize.width()) - totalSize.setWidth(size.width()); - } - m_totalSize = totalSize.toSize(); - setMinimumSize(m_totalSize); - emit zoomChanged(m_zoom); - qCDebug(lcExample) << "total size" << m_totalSize; - m_pageCache.clear(); - update(); -} - -void SequentialPageWidget::documentStatusChanged() -{ - m_pageSizes.clear(); - m_topPageShowing = 0; - - if (m_document->status() == QPdfDocument::Ready) { - for (int page = 0; page < m_document->pageCount(); ++page) - m_pageSizes.append(m_document->pageSize(page)); - } - - invalidate(); -} - -void SequentialPageWidget::pageLoaded(int page, qreal zoom, QImage image) -{ - Q_UNUSED(zoom) - if (m_cachedPagesLRU.length() > m_pageCacheLimit) - m_pageCache.remove(m_cachedPagesLRU.takeFirst()); - m_pageCache.insert(page, image); - m_cachedPagesLRU.append(page); - update(); -} - -int SequentialPageWidget::pageCount() -{ - return m_pageSizes.count(); -} - -void SequentialPageWidget::paintEvent(QPaintEvent * event) -{ - QPainter painter(this); - painter.fillRect(event->rect(), m_background); - - if (m_pageSizes.isEmpty()) - return; - - // Find the first page that needs to be rendered - int page = 0; - int y = 0; - while (page < pageCount()) { - QSizeF size = pageSize(page); - int height = size.toSize().height(); - if (y + height >= event->rect().top()) - break; - y += height + m_pageSpacing; - ++page; - } - y += m_pageSpacing; - m_topPageShowing = page; - - // Actually render pages - while (y < event->rect().bottom() && page < pageCount()) { - QSizeF size = pageSize(page); - if (m_pageCache.contains(page)) { - const QImage &img = m_pageCache[page]; - painter.fillRect((width() - img.width()) / 2, y, size.width(), size.height(), Qt::white); - painter.drawImage((width() - img.width()) / 2, y, img); - } else { - painter.fillRect((width() - size.width()) / 2, y, size.width(), size.height(), m_placeholderBackground); - painter.drawPixmap((size.width() - m_placeholderIcon.width()) / 2, - (size.height() - m_placeholderIcon.height()) / 2, m_placeholderIcon); - m_pageRenderer->requestPage(page, m_screenResolution * m_zoom); - } - y += size.height() + m_pageSpacing; - ++page; - } - m_bottomPageShowing = page - 1; - emit showingPageRange(m_topPageShowing, m_bottomPageShowing); -} - -qreal SequentialPageWidget::yForPage(int endPage) -{ - // TODO maybe put this loop into a page iterator class - int y = m_pageSpacing; - for (int page = 0; page < pageCount() && page < endPage; ++page) { - QSizeF size = pageSize(page); - int height = size.toSize().height(); - y += height + m_pageSpacing; - } - return y; -} diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h deleted file mode 100644 index 85f3571..0000000 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtPDF module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SEQUENTIALPAGEWIDGET_H -#define SEQUENTIALPAGEWIDGET_H - -#include - -class QPdfDocument; -class PageRenderer; - -class SequentialPageWidget : public QWidget -{ - Q_OBJECT -public: - explicit SequentialPageWidget(QWidget *parent = 0); - ~SequentialPageWidget(); - - void paintEvent(QPaintEvent * event); - qreal zoom() { return m_zoom; } - qreal yForPage(int page); - int topPageShowing() { return m_topPageShowing; } - int bottomPageShowing() { return m_bottomPageShowing; } - - void setDocument(QPdfDocument *document); - -public slots: - void setZoom(qreal factor); - void invalidate(); - -signals: - void showingPageRange(int start, int end); - void zoomChanged(qreal factor); - -private slots: - void documentStatusChanged(); - void pageLoaded(int page, qreal zoom, QImage image); - -private: - int pageCount(); - QSizeF pageSize(int page); - void render(int page); - -private: - QHash m_pageCache; - QVector m_cachedPagesLRU; - int m_pageCacheLimit; - QVector m_pageSizes; - PageRenderer *m_pageRenderer; - QBrush m_background; - QPixmap m_placeholderIcon; - QBrush m_placeholderBackground; - int m_pageSpacing; - int m_topPageShowing; - int m_bottomPageShowing; - QSize m_totalSize; - qreal m_zoom; - qreal m_screenResolution; // pixels per point - - QPdfDocument *m_document; -}; - -#endif // SEQUENTIALPAGEWIDGET_H -- cgit v1.2.3