summaryrefslogtreecommitdiffstats
path: root/examples/pdfwidgets/pdfviewer
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-01-24 11:27:17 +0100
committerMichal Klocek <michal.klocek@qt.io>2019-11-25 12:01:39 +0100
commitf8d12697a3830d331589229aec6d83e6686f77fc (patch)
treee3ccedeaefddc2cf6241c16302bc875cf7b2e882 /examples/pdfwidgets/pdfviewer
parent34f81299d8655c637526dcd0dfe522b72c58f1a0 (diff)
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 <oswald.buddenhagen@qt.io>
Diffstat (limited to 'examples/pdfwidgets/pdfviewer')
-rw-r--r--examples/pdfwidgets/pdfviewer/images/busy.pngbin0 -> 172 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/fileopen.pngbin0 -> 1771 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-next-24.pngbin0 -> 782 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-previous-24.pngbin0 -> 797 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-in-24.pngbin0 -> 1302 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-in-32.pngbin0 -> 1873 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-out-24.pngbin0 -> 1247 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-out-32.pngbin0 -> 1749 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/main.cpp51
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.cpp170
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.h89
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.ui173
-rw-r--r--examples/pdfwidgets/pdfviewer/pagerenderer.cpp105
-rw-r--r--examples/pdfwidgets/pdfviewer/pagerenderer.h80
-rw-r--r--examples/pdfwidgets/pdfviewer/pdfviewer.pro21
-rw-r--r--examples/pdfwidgets/pdfviewer/resources.qrc12
-rw-r--r--examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp192
-rw-r--r--examples/pdfwidgets/pdfviewer/sequentialpagewidget.h96
18 files changed, 989 insertions, 0 deletions
diff --git a/examples/pdfwidgets/pdfviewer/images/busy.png b/examples/pdfwidgets/pdfviewer/images/busy.png
new file mode 100644
index 000000000..69056c479
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/busy.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/fileopen.png b/examples/pdfwidgets/pdfviewer/images/fileopen.png
new file mode 100644
index 000000000..33e0d6394
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/fileopen.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-next-24.png b/examples/pdfwidgets/pdfviewer/images/go-next-24.png
new file mode 100644
index 000000000..9a55ef3d8
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-next-24.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-previous-24.png b/examples/pdfwidgets/pdfviewer/images/go-previous-24.png
new file mode 100644
index 000000000..2ea769eb8
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-previous-24.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png b/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png
new file mode 100644
index 000000000..d29b142b6
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png b/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png
new file mode 100644
index 000000000..34d70af37
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png b/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png
new file mode 100644
index 000000000..19703474f
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png b/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png
new file mode 100644
index 000000000..b83220661
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/main.cpp b/examples/pdfwidgets/pdfviewer/main.cpp
new file mode 100644
index 000000000..20fa6f8cd
--- /dev/null
+++ b/examples/pdfwidgets/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 <QApplication>
+#include <QUrl>
+
+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/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
new file mode 100644
index 000000000..d865a8bdd
--- /dev/null
+++ b/examples/pdfwidgets/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 <QFileDialog>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QPdfDocument>
+#include <QScroller>
+#include <QtMath>
+
+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/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h
new file mode 100644
index 000000000..dedc81267
--- /dev/null
+++ b/examples/pdfwidgets/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 <QLoggingCategory>
+#include <QMainWindow>
+
+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/pdfwidgets/pdfviewer/mainwindow.ui b/examples/pdfwidgets/pdfviewer/mainwindow.ui
new file mode 100644
index 000000000..7070619b9
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.ui
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>380</width>
+ <height>200</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2"/>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <addaction name="actionOpen"/>
+ <addaction name="actionQuit"/>
+ </widget>
+ <widget class="QMenu" name="menuHelp">
+ <property name="title">
+ <string>Help</string>
+ </property>
+ <addaction name="actionAbout"/>
+ <addaction name="actionAbout_Qt"/>
+ </widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>View</string>
+ </property>
+ <addaction name="actionZoom_In"/>
+ <addaction name="actionZoom_Out"/>
+ <addaction name="actionPrevious_Page"/>
+ <addaction name="actionNext_Page"/>
+ </widget>
+ <addaction name="menuFile"/>
+ <addaction name="menuView"/>
+ <addaction name="menuHelp"/>
+ </widget>
+ <widget class="QToolBar" name="mainToolBar">
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ <addaction name="actionOpen"/>
+ <addaction name="separator"/>
+ <addaction name="actionZoom_Out"/>
+ <addaction name="actionZoom_In"/>
+ <addaction name="separator"/>
+ <addaction name="actionGo"/>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ <action name="actionOpen">
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/icons/images/fileopen.png</normaloff>:/icons/images/fileopen.png</iconset>
+ </property>
+ <property name="text">
+ <string>Open...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionQuit">
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="actionAbout">
+ <property name="text">
+ <string>About</string>
+ </property>
+ </action>
+ <action name="actionAbout_Qt">
+ <property name="text">
+ <string>About Qt</string>
+ </property>
+ </action>
+ <action name="actionZoom_In">
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/icons/images/zoom-in-24.png</normaloff>:/icons/images/zoom-in-24.png</iconset>
+ </property>
+ <property name="text">
+ <string>Zoom In</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+=</string>
+ </property>
+ </action>
+ <action name="actionZoom_Out">
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/icons/images/zoom-out-24.png</normaloff>:/icons/images/zoom-out-24.png</iconset>
+ </property>
+ <property name="text">
+ <string>Zoom Out</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+-</string>
+ </property>
+ </action>
+ <action name="actionGo">
+ <property name="text">
+ <string>Go</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to Page</string>
+ </property>
+ </action>
+ <action name="actionPrevious_Page">
+ <property name="text">
+ <string>Previous Page</string>
+ </property>
+ <property name="shortcut">
+ <string>PgUp</string>
+ </property>
+ </action>
+ <action name="actionNext_Page">
+ <property name="text">
+ <string>Next Page</string>
+ </property>
+ <property name="shortcut">
+ <string>PgDown</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/examples/pdfwidgets/pdfviewer/pagerenderer.cpp b/examples/pdfwidgets/pdfviewer/pagerenderer.cpp
new file mode 100644
index 000000000..c8f245640
--- /dev/null
+++ b/examples/pdfwidgets/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 <QElapsedTimer>
+#include <QLoggingCategory>
+#include <QPainter>
+#include <QPdfDocument>
+#include <QUrl>
+
+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/pdfwidgets/pdfviewer/pagerenderer.h b/examples/pdfwidgets/pdfviewer/pagerenderer.h
new file mode 100644
index 000000000..5feccaac6
--- /dev/null
+++ b/examples/pdfwidgets/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 <QImage>
+#include <QThread>
+
+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/pdfwidgets/pdfviewer/pdfviewer.pro b/examples/pdfwidgets/pdfviewer/pdfviewer.pro
new file mode 100644
index 000000000..10cacce6e
--- /dev/null
+++ b/examples/pdfwidgets/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/pdfwidgets/pdfviewer/resources.qrc b/examples/pdfwidgets/pdfviewer/resources.qrc
new file mode 100644
index 000000000..02d9655b4
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/resources.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/icons">
+ <file>images/fileopen.png</file>
+ <file>images/go-next-24.png</file>
+ <file>images/go-previous-24.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+ <file>images/zoom-out-32.png</file>
+ <file>images/busy.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp b/examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp
new file mode 100644
index 000000000..904bc17d2
--- /dev/null
+++ b/examples/pdfwidgets/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 <QPaintEvent>
+#include <QPainter>
+#include <QPdfDocument>
+#include <QGuiApplication>
+#include <QScreen>
+#include <QLoggingCategory>
+#include <QElapsedTimer>
+
+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/pdfwidgets/pdfviewer/sequentialpagewidget.h b/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h
new file mode 100644
index 000000000..85f35713c
--- /dev/null
+++ b/examples/pdfwidgets/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 <QWidget>
+
+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<int, QImage> m_pageCache;
+ QVector<int> m_cachedPagesLRU;
+ int m_pageCacheLimit;
+ QVector<QSizeF> 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