From 775b42e0f55d603b5039834de8151ac783173852 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 15:23:45 +0100 Subject: initial single-threaded implementation of pdfviewer example --- examples/widgets/pdfviewer/main.cpp | 15 +++++ examples/widgets/pdfviewer/mainwindow.cpp | 39 +++++++++++++ examples/widgets/pdfviewer/mainwindow.h | 34 +++++++++++ examples/widgets/pdfviewer/mainwindow.ui | 67 ++++++++++++++++++++++ examples/widgets/pdfviewer/pdfviewer.pro | 12 ++++ .../widgets/pdfviewer/sequentialpagewidget.cpp | 63 ++++++++++++++++++++ examples/widgets/pdfviewer/sequentialpagewidget.h | 34 +++++++++++ 7 files changed, 264 insertions(+) create mode 100644 examples/widgets/pdfviewer/main.cpp create mode 100644 examples/widgets/pdfviewer/mainwindow.cpp create mode 100644 examples/widgets/pdfviewer/mainwindow.h create mode 100644 examples/widgets/pdfviewer/mainwindow.ui create mode 100644 examples/widgets/pdfviewer/pdfviewer.pro create mode 100644 examples/widgets/pdfviewer/sequentialpagewidget.cpp create mode 100644 examples/widgets/pdfviewer/sequentialpagewidget.h (limited to 'examples') diff --git a/examples/widgets/pdfviewer/main.cpp b/examples/widgets/pdfviewer/main.cpp new file mode 100644 index 000000000..51a3f9883 --- /dev/null +++ b/examples/widgets/pdfviewer/main.cpp @@ -0,0 +1,15 @@ +#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 new file mode 100644 index 000000000..1316dede1 --- /dev/null +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -0,0 +1,39 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include +#include + +Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer") + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_doc(new QPdfDocument(this)) +{ + ui->setupUi(this); + ui->pageWidget->setDocument(m_doc); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::open(const QUrl &docLocation) +{ + if (docLocation.isLocalFile()) + m_doc->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())); + } +} + +void MainWindow::on_actionOpen_triggered() +{ + QUrl toOpen = QFileDialog::getOpenFileUrl(this); + if (toOpen.isValid()) + open(toOpen); +} diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h new file mode 100644 index 000000000..e31f0b970 --- /dev/null +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -0,0 +1,34 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +namespace Ui { +class MainWindow; +} + +class QPdfDocument; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +public slots: + void open(const QUrl &docLocation); + +private slots: + void on_actionOpen_triggered(); + +private: + Ui::MainWindow *ui; + QPdfDocument *m_doc; +}; + +#endif // MAINWINDOW_H diff --git a/examples/widgets/pdfviewer/mainwindow.ui b/examples/widgets/pdfviewer/mainwindow.ui new file mode 100644 index 000000000..16994fa57 --- /dev/null +++ b/examples/widgets/pdfviewer/mainwindow.ui @@ -0,0 +1,67 @@ + + + MainWindow + + + + 0 + 0 + 400 + 300 + + + + MainWindow + + + + + + + + + + + + 0 + 0 + 400 + 19 + + + + + File + + + + + + + + TopToolBarArea + + + false + + + + + + + Open... + + + + + + + SequentialPageWidget + QWidget +
sequentialpagewidget.h
+ 1 +
+
+ + +
diff --git a/examples/widgets/pdfviewer/pdfviewer.pro b/examples/widgets/pdfviewer/pdfviewer.pro new file mode 100644 index 000000000..47a13f508 --- /dev/null +++ b/examples/widgets/pdfviewer/pdfviewer.pro @@ -0,0 +1,12 @@ +QT += core gui widgets pdf +TARGET = pdfviewer +TEMPLATE = app + +SOURCES += main.cpp\ + mainwindow.cpp \ + sequentialpagewidget.cpp + +HEADERS += mainwindow.h \ + sequentialpagewidget.h + +FORMS += mainwindow.ui diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp new file mode 100644 index 000000000..5de4f2ee8 --- /dev/null +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -0,0 +1,63 @@ +#include "sequentialpagewidget.h" +#include +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +SequentialPageWidget::SequentialPageWidget(QWidget *parent) + : QWidget(parent) + , m_doc(Q_NULLPTR) + , m_background(Qt::darkGray) + , m_pageSpacing(3) + , m_zoom(1.) + , m_top(0.) + , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) +{ +} + +SequentialPageWidget::~SequentialPageWidget() +{ + +} + +void SequentialPageWidget::setDocument(QPdfDocument *doc) +{ + m_doc = doc; +} + +void SequentialPageWidget::setZoom(qreal factor) +{ + m_zoom = factor; + m_pageCache.clear(); + update(); +} + +void SequentialPageWidget::paintEvent(QPaintEvent * event) +{ + QPainter painter(this); + if (!m_doc) { + painter.drawText(rect(), Qt::AlignCenter, tr("no document loaded")); + return; + } + + painter.fillRect(event->rect(), m_background); + qCDebug(lcExample) << event->rect() << m_doc->pageCount(); + + int page = 0; // qFloor(m_top); + int y = 0; // TODO event->rect().top(); + while (y < event->rect().bottom() && page < m_doc->pageCount()) { + QSizeF size = m_doc->pageSize(page) * m_screenResolution * m_zoom; + if (!m_pageCache.contains(page)) { + qCDebug(lcExample) << "rendering page" << page << "to size" << size; + m_pageCache.insert(page, QPixmap::fromImage(m_doc->render(page, size))); + } + const QPixmap &pm = m_pageCache[page]; + painter.drawPixmap(0, y, pm); + y += pm.height() + m_pageSpacing; + ++page; + } +} diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h new file mode 100644 index 000000000..6741fe37e --- /dev/null +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -0,0 +1,34 @@ +#ifndef SEQUENTIALPAGEWIDGET_H +#define SEQUENTIALPAGEWIDGET_H + +#include + +class QPdfDocument; + +class SequentialPageWidget : public QWidget +{ + Q_OBJECT +public: + explicit SequentialPageWidget(QWidget *parent = 0); + ~SequentialPageWidget(); + + void paintEvent(QPaintEvent * event); + +public slots: + void setDocument(QPdfDocument *doc); + void setZoom(qreal factor); + +private: + void render(int page); + +private: + QPdfDocument *m_doc; + QHash m_pageCache; + QBrush m_background; + int m_pageSpacing; + qreal m_zoom; + qreal m_top; // 1.5 means start from the bottom half of page 1 + qreal m_screenResolution; // pixels per point +}; + +#endif // SEQUENTIALPAGEWIDGET_H -- cgit v1.2.3 From 157b3e8e0aed03e2131c2900cffbb16e3ea34663 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 16:39:28 +0100 Subject: pdfviewer example: can scroll through pages and render on demand --- examples/widgets/pdfviewer/mainwindow.cpp | 22 +++++++++- examples/widgets/pdfviewer/mainwindow.h | 3 ++ examples/widgets/pdfviewer/mainwindow.ui | 25 +++++++---- .../widgets/pdfviewer/sequentialpagewidget.cpp | 48 ++++++++++++++++++---- examples/widgets/pdfviewer/sequentialpagewidget.h | 8 +++- 5 files changed, 87 insertions(+), 19 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index 1316dede1..e5b29edfd 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -4,6 +4,7 @@ #include #include #include +#include "sequentialpagewidget.h" Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer") @@ -11,9 +12,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_doc(new QPdfDocument(this)) + , m_pageWidget(new SequentialPageWidget(this)) { ui->setupUi(this); - ui->pageWidget->setDocument(m_doc); + m_pageWidget->setDocument(m_doc); + ui->scrollArea->setWidget(m_pageWidget); + connect(m_pageWidget, SIGNAL(showingPageRange(int,int)), + this, SLOT(showingPageRange(int,int)), Qt::QueuedConnection); } MainWindow::~MainWindow() @@ -29,11 +34,24 @@ void MainWindow::open(const QUrl &docLocation) 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())); } + // TODO: connect to signal from document + m_pageWidget->invalidate(); + 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)); } void MainWindow::on_actionOpen_triggered() { - QUrl toOpen = QFileDialog::getOpenFileUrl(this); + QUrl toOpen = QFileDialog::getOpenFileUrl(this, tr("Choose a PDF"), QUrl(), "Portable Documents (*.pdf)"); if (toOpen.isValid()) open(toOpen); } diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h index e31f0b970..bcad93ebb 100644 --- a/examples/widgets/pdfviewer/mainwindow.h +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -11,6 +11,7 @@ class MainWindow; } class QPdfDocument; +class SequentialPageWidget; class MainWindow : public QMainWindow { @@ -24,11 +25,13 @@ public slots: void open(const QUrl &docLocation); private slots: + void showingPageRange(int start, int end); void on_actionOpen_triggered(); private: Ui::MainWindow *ui; QPdfDocument *m_doc; + SequentialPageWidget *m_pageWidget; }; #endif // MAINWINDOW_H diff --git a/examples/widgets/pdfviewer/mainwindow.ui b/examples/widgets/pdfviewer/mainwindow.ui index 16994fa57..f1f90b307 100644 --- a/examples/widgets/pdfviewer/mainwindow.ui +++ b/examples/widgets/pdfviewer/mainwindow.ui @@ -16,7 +16,22 @@ - + + + true + + + + + 0 + 0 + 380 + 210 + + + + + @@ -54,14 +69,6 @@ - - - SequentialPageWidget - QWidget -
sequentialpagewidget.h
- 1 -
-
diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index 5de4f2ee8..e7dd08746 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -14,25 +14,45 @@ SequentialPageWidget::SequentialPageWidget(QWidget *parent) , m_background(Qt::darkGray) , m_pageSpacing(3) , m_zoom(1.) - , m_top(0.) , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) { } SequentialPageWidget::~SequentialPageWidget() { - } void SequentialPageWidget::setDocument(QPdfDocument *doc) { m_doc = doc; + invalidate(); } void SequentialPageWidget::setZoom(qreal factor) { m_zoom = factor; + invalidate(); +} + +QSizeF SequentialPageWidget::pageSize(int page) +{ + return m_doc->pageSize(page) * m_screenResolution * m_zoom; +} + +void SequentialPageWidget::invalidate() +{ m_pageCache.clear(); + QSizeF totalSize(0, m_pageSpacing); + for (int page = 0; page < m_doc->pageCount(); ++page) { + QSizeF size = pageSize(page); + qDebug() << "page" << page << "size" << size; + totalSize.setHeight(totalSize.height() + size.height()); + if (size.width() > totalSize.width()) + totalSize.setWidth(size.width()); + } + m_totalSize = totalSize.toSize(); + setMinimumSize(m_totalSize); + qCDebug(lcExample) << "total size" << m_totalSize; update(); } @@ -45,19 +65,33 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) } painter.fillRect(event->rect(), m_background); - qCDebug(lcExample) << event->rect() << m_doc->pageCount(); - int page = 0; // qFloor(m_top); - int y = 0; // TODO event->rect().top(); + // Find the first page that needs to be rendered + int page = 0; + int y = 0; + while (page < m_doc->pageCount()) { + QSizeF size = pageSize(page); + int height = size.toSize().height(); + if (y + height >= event->rect().top()) + break; + y += height; + ++page; + } + y += m_pageSpacing; + int startPage = page; + + // Actually render pages while (y < event->rect().bottom() && page < m_doc->pageCount()) { - QSizeF size = m_doc->pageSize(page) * m_screenResolution * m_zoom; if (!m_pageCache.contains(page)) { + QSizeF size = pageSize(page); qCDebug(lcExample) << "rendering page" << page << "to size" << size; m_pageCache.insert(page, QPixmap::fromImage(m_doc->render(page, size))); } const QPixmap &pm = m_pageCache[page]; - painter.drawPixmap(0, y, pm); + painter.drawPixmap((width() - pm.width()) / 2, y, pm); y += pm.height() + m_pageSpacing; ++page; } + + emit showingPageRange(startPage, page - 1); } diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 6741fe37e..44b27faad 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -2,6 +2,7 @@ #define SEQUENTIALPAGEWIDGET_H #include +#include class QPdfDocument; @@ -17,8 +18,13 @@ public: public slots: void setDocument(QPdfDocument *doc); void setZoom(qreal factor); + void invalidate(); + +signals: + void showingPageRange(int start, int end); private: + QSizeF pageSize(int page); void render(int page); private: @@ -26,8 +32,8 @@ private: QHash m_pageCache; QBrush m_background; int m_pageSpacing; + QSize m_totalSize; qreal m_zoom; - qreal m_top; // 1.5 means start from the bottom half of page 1 qreal m_screenResolution; // pixels per point }; -- cgit v1.2.3 From 21015ae4d3fbd18b0739587f99a47291d5a5de3f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 19:05:43 +0100 Subject: pdf viewer example: more typical features zooming field for setting zoom, up/down buttons field for setting and viewing page number, up/down actions icons for toolbar actions --- examples/widgets/pdfviewer/images/fileopen.png | Bin 0 -> 1771 bytes examples/widgets/pdfviewer/images/go-next-24.png | Bin 0 -> 782 bytes .../widgets/pdfviewer/images/go-previous-24.png | Bin 0 -> 797 bytes examples/widgets/pdfviewer/images/zoom-in-24.png | Bin 0 -> 1302 bytes examples/widgets/pdfviewer/images/zoom-in-32.png | Bin 0 -> 1873 bytes examples/widgets/pdfviewer/images/zoom-out-24.png | Bin 0 -> 1247 bytes examples/widgets/pdfviewer/images/zoom-out-32.png | Bin 0 -> 1749 bytes examples/widgets/pdfviewer/mainwindow.cpp | 74 +++++++++++++++ examples/widgets/pdfviewer/mainwindow.h | 15 +++ examples/widgets/pdfviewer/mainwindow.ui | 103 ++++++++++++++++++++- examples/widgets/pdfviewer/pdfviewer.pro | 3 + examples/widgets/pdfviewer/resources.qrc | 11 +++ .../widgets/pdfviewer/sequentialpagewidget.cpp | 22 ++++- examples/widgets/pdfviewer/sequentialpagewidget.h | 8 +- 14 files changed, 230 insertions(+), 6 deletions(-) create mode 100644 examples/widgets/pdfviewer/images/fileopen.png create mode 100644 examples/widgets/pdfviewer/images/go-next-24.png create mode 100644 examples/widgets/pdfviewer/images/go-previous-24.png create mode 100644 examples/widgets/pdfviewer/images/zoom-in-24.png create mode 100644 examples/widgets/pdfviewer/images/zoom-in-32.png create mode 100644 examples/widgets/pdfviewer/images/zoom-out-24.png create mode 100644 examples/widgets/pdfviewer/images/zoom-out-32.png create mode 100644 examples/widgets/pdfviewer/resources.qrc (limited to 'examples') diff --git a/examples/widgets/pdfviewer/images/fileopen.png b/examples/widgets/pdfviewer/images/fileopen.png new file mode 100644 index 000000000..33e0d6394 Binary files /dev/null and b/examples/widgets/pdfviewer/images/fileopen.png differ diff --git a/examples/widgets/pdfviewer/images/go-next-24.png b/examples/widgets/pdfviewer/images/go-next-24.png new file mode 100644 index 000000000..9a55ef3d8 Binary files /dev/null and b/examples/widgets/pdfviewer/images/go-next-24.png differ diff --git a/examples/widgets/pdfviewer/images/go-previous-24.png b/examples/widgets/pdfviewer/images/go-previous-24.png new file mode 100644 index 000000000..2ea769eb8 Binary files /dev/null and b/examples/widgets/pdfviewer/images/go-previous-24.png differ diff --git a/examples/widgets/pdfviewer/images/zoom-in-24.png b/examples/widgets/pdfviewer/images/zoom-in-24.png new file mode 100644 index 000000000..d29b142b6 Binary files /dev/null and b/examples/widgets/pdfviewer/images/zoom-in-24.png differ diff --git a/examples/widgets/pdfviewer/images/zoom-in-32.png b/examples/widgets/pdfviewer/images/zoom-in-32.png new file mode 100644 index 000000000..34d70af37 Binary files /dev/null and b/examples/widgets/pdfviewer/images/zoom-in-32.png differ diff --git a/examples/widgets/pdfviewer/images/zoom-out-24.png b/examples/widgets/pdfviewer/images/zoom-out-24.png new file mode 100644 index 000000000..19703474f Binary files /dev/null and b/examples/widgets/pdfviewer/images/zoom-out-24.png differ diff --git a/examples/widgets/pdfviewer/images/zoom-out-32.png b/examples/widgets/pdfviewer/images/zoom-out-32.png new file mode 100644 index 000000000..b83220661 Binary files /dev/null and b/examples/widgets/pdfviewer/images/zoom-out-32.png differ diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index e5b29edfd..df0c5a366 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -2,10 +2,14 @@ #include "ui_mainwindow.h" #include +#include #include #include +#include #include "sequentialpagewidget.h" +const qreal zoomMultiplier = qSqrt(2.0); + Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer") MainWindow::MainWindow(QWidget *parent) @@ -13,12 +17,24 @@ MainWindow::MainWindow(QWidget *parent) , ui(new Ui::MainWindow) , m_doc(new QPdfDocument(this)) , m_pageWidget(new SequentialPageWidget(this)) + , m_zoomEdit(new QLineEdit(this)) + , m_pageEdit(new QLineEdit(this)) { ui->setupUi(this); m_pageWidget->setDocument(m_doc); 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())); } MainWindow::~MainWindow() @@ -47,6 +63,20 @@ void MainWindow::showingPageRange(int start, int 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() @@ -55,3 +85,47 @@ void MainWindow::on_actionOpen_triggered() 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 index bcad93ebb..5d638ec33 100644 --- a/examples/widgets/pdfviewer/mainwindow.h +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -10,6 +10,7 @@ namespace Ui { class MainWindow; } +class QLineEdit; class QPdfDocument; class SequentialPageWidget; @@ -26,12 +27,26 @@ public slots: 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; QPdfDocument *m_doc; SequentialPageWidget *m_pageWidget; + QLineEdit *m_zoomEdit; + QLineEdit *m_pageEdit; }; #endif // MAINWINDOW_H diff --git a/examples/widgets/pdfviewer/mainwindow.ui b/examples/widgets/pdfviewer/mainwindow.ui index f1f90b307..7070619b9 100644 --- a/examples/widgets/pdfviewer/mainwindow.ui +++ b/examples/widgets/pdfviewer/mainwindow.ui @@ -26,7 +26,7 @@ 0 0 380 - 210 + 200 @@ -49,8 +49,27 @@ File + + + + + Help + + + + + + + View + + + + + + + @@ -60,15 +79,95 @@ 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/pdfviewer.pro b/examples/widgets/pdfviewer/pdfviewer.pro index 47a13f508..babcd85e6 100644 --- a/examples/widgets/pdfviewer/pdfviewer.pro +++ b/examples/widgets/pdfviewer/pdfviewer.pro @@ -10,3 +10,6 @@ HEADERS += mainwindow.h \ sequentialpagewidget.h FORMS += mainwindow.ui + +RESOURCES += \ + resources.qrc diff --git a/examples/widgets/pdfviewer/resources.qrc b/examples/widgets/pdfviewer/resources.qrc new file mode 100644 index 000000000..945c59565 --- /dev/null +++ b/examples/widgets/pdfviewer/resources.qrc @@ -0,0 +1,11 @@ + + + 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 + + diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index e7dd08746..a9d5c428b 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -13,6 +13,7 @@ SequentialPageWidget::SequentialPageWidget(QWidget *parent) , m_doc(Q_NULLPTR) , m_background(Qt::darkGray) , m_pageSpacing(3) + , m_topPageShowing(0) , m_zoom(1.) , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) { @@ -25,12 +26,14 @@ SequentialPageWidget::~SequentialPageWidget() void SequentialPageWidget::setDocument(QPdfDocument *doc) { m_doc = doc; + m_topPageShowing = 0; invalidate(); } void SequentialPageWidget::setZoom(qreal factor) { m_zoom = factor; + emit zoomChanged(factor); invalidate(); } @@ -52,6 +55,7 @@ void SequentialPageWidget::invalidate() } m_totalSize = totalSize.toSize(); setMinimumSize(m_totalSize); + emit zoomChanged(m_zoom); qCDebug(lcExample) << "total size" << m_totalSize; update(); } @@ -74,11 +78,11 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) int height = size.toSize().height(); if (y + height >= event->rect().top()) break; - y += height; + y += height + m_pageSpacing; ++page; } y += m_pageSpacing; - int startPage = page; + m_topPageShowing = page; // Actually render pages while (y < event->rect().bottom() && page < m_doc->pageCount()) { @@ -92,6 +96,18 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) y += pm.height() + m_pageSpacing; ++page; } + m_bottomPageShowing = page - 1; + emit showingPageRange(m_topPageShowing, m_bottomPageShowing); +} - emit showingPageRange(startPage, page - 1); +qreal SequentialPageWidget::yForPage(int endPage) +{ + // TODO maybe put this loop into a page iterator class + int y = m_pageSpacing; + for (int page = 0; page < m_doc->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 index 44b27faad..07fef477d 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -2,7 +2,6 @@ #define SEQUENTIALPAGEWIDGET_H #include -#include class QPdfDocument; @@ -14,6 +13,10 @@ public: ~SequentialPageWidget(); void paintEvent(QPaintEvent * event); + qreal zoom() { return m_zoom; } + qreal yForPage(int page); + int topPageShowing() { return m_topPageShowing; } + int bottomPageShowing() { return m_bottomPageShowing; } public slots: void setDocument(QPdfDocument *doc); @@ -22,6 +25,7 @@ public slots: signals: void showingPageRange(int start, int end); + void zoomChanged(qreal factor); private: QSizeF pageSize(int page); @@ -32,6 +36,8 @@ private: QHash m_pageCache; QBrush m_background; int m_pageSpacing; + int m_topPageShowing; + int m_bottomPageShowing; QSize m_totalSize; qreal m_zoom; qreal m_screenResolution; // pixels per point -- cgit v1.2.3 From af10ffdc4cf31c29a15a83ed7dd9b7ed516585ea Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 19:20:01 +0100 Subject: pdfviewer example: add rendering stats --- .../widgets/pdfviewer/sequentialpagewidget.cpp | 22 +++++++++++++++++++++- examples/widgets/pdfviewer/sequentialpagewidget.h | 6 ++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index a9d5c428b..5bac32c61 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -5,6 +5,7 @@ #include #include #include +#include Q_DECLARE_LOGGING_CATEGORY(lcExample) @@ -16,6 +17,10 @@ SequentialPageWidget::SequentialPageWidget(QWidget *parent) , m_topPageShowing(0) , m_zoom(1.) , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) + , m_minRenderTime(1000000000.) + , m_maxRenderTime(0.) + , m_totalRenderTime(0.) + , m_totalPagesRendered(0) { } @@ -83,13 +88,23 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) } y += m_pageSpacing; m_topPageShowing = page; + int previousRendered = m_totalPagesRendered; // Actually render pages while (y < event->rect().bottom() && page < m_doc->pageCount()) { if (!m_pageCache.contains(page)) { QSizeF size = pageSize(page); qCDebug(lcExample) << "rendering page" << page << "to size" << size; - m_pageCache.insert(page, QPixmap::fromImage(m_doc->render(page, size))); + QElapsedTimer timer; timer.start(); + const QImage &img = m_doc->render(page, size); + 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; + m_pageCache.insert(page, QPixmap::fromImage(img)); } const QPixmap &pm = m_pageCache[page]; painter.drawPixmap((width() - pm.width()) / 2, y, pm); @@ -98,6 +113,11 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) } m_bottomPageShowing = page - 1; emit showingPageRange(m_topPageShowing, m_bottomPageShowing); + + if (m_totalPagesRendered != previousRendered) + qCDebug(lcExample) << "rendering time: min" << m_minRenderTime << + "avg" << m_totalRenderTime / m_totalPagesRendered << + "max" << m_maxRenderTime; } qreal SequentialPageWidget::yForPage(int endPage) diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 07fef477d..3d91279cf 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -41,6 +41,12 @@ private: QSize m_totalSize; qreal m_zoom; qreal m_screenResolution; // pixels per point + + // performance statistics + qreal m_minRenderTime; + qreal m_maxRenderTime; + qreal m_totalRenderTime; + int m_totalPagesRendered; }; #endif // SEQUENTIALPAGEWIDGET_H -- cgit v1.2.3 From 6d168f41c9f38760b234fb22652a668716f43375 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 21:13:10 +0100 Subject: pdfviewer example: add threaded PageCache thread fixes --- examples/widgets/pdfviewer/images/busy.png | Bin 0 -> 172 bytes examples/widgets/pdfviewer/pagecache.cpp | 106 +++++++++++++++++++++ examples/widgets/pdfviewer/pagecache.h | 46 +++++++++ examples/widgets/pdfviewer/pdfviewer.pro | 6 +- examples/widgets/pdfviewer/resources.qrc | 1 + .../widgets/pdfviewer/sequentialpagewidget.cpp | 39 +++----- examples/widgets/pdfviewer/sequentialpagewidget.h | 9 +- 7 files changed, 172 insertions(+), 35 deletions(-) create mode 100644 examples/widgets/pdfviewer/images/busy.png create mode 100644 examples/widgets/pdfviewer/pagecache.cpp create mode 100644 examples/widgets/pdfviewer/pagecache.h (limited to 'examples') diff --git a/examples/widgets/pdfviewer/images/busy.png b/examples/widgets/pdfviewer/images/busy.png new file mode 100644 index 000000000..69056c479 Binary files /dev/null and b/examples/widgets/pdfviewer/images/busy.png differ diff --git a/examples/widgets/pdfviewer/pagecache.cpp b/examples/widgets/pdfviewer/pagecache.cpp new file mode 100644 index 000000000..5943b90c2 --- /dev/null +++ b/examples/widgets/pdfviewer/pagecache.cpp @@ -0,0 +1,106 @@ +#include "pagecache.h" +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +PageCache::PageCache(QPdfDocument *doc, qreal zoom) + : QObject(Q_NULLPTR) + , m_thread(new QThread(this)) + , m_doc(doc) + , m_zoom(zoom) + , m_placeholderIcon(":icons/images/busy.png") + , m_placeholderBackground(Qt::white) + , m_minRenderTime(1000000000.) + , m_maxRenderTime(0.) + , m_totalRenderTime(0.) + , m_totalPagesRendered(0) +{ + moveToThread(m_thread); + connect(this, &PageCache::pagesNeeded, this, &PageCache::run, Qt::QueuedConnection); +} + +PageCache::~PageCache() +{ +} + +/*! + Get the result from the cache, + or a placeholder pixmap if unavailable. + */ +QPixmap PageCache::get(int page) +{ + m_lastPageRequested = page; + if (m_pageCache.contains(page)) + return m_pageCache[page]; + if (!m_thread->isRunning()) + m_thread->start(QThread::LowestPriority); + emit pagesNeeded(); + QSizeF sizeF = m_doc->pageSize(page); + if (!sizeF.isValid()) + return QPixmap(); + QSize size = QSizeF(sizeF * m_zoom).toSize(); + QPixmap placeholder(size); + { + QPainter painter(&placeholder); + painter.fillRect(QRect(QPoint(), size), m_placeholderBackground); + painter.drawPixmap((size.width() - m_placeholderIcon.width()) / 2, + (size.height() - m_placeholderIcon.height()) / 2, m_placeholderIcon); + } + return placeholder; +} + +void PageCache::run() +{ + int lastPageRequested = m_lastPageRequested; + int forward = lastPageRequested; + int backward = lastPageRequested - 1; + while (true) { + bool done = true; + if (lastPageRequested != m_lastPageRequested) { + lastPageRequested = m_lastPageRequested; + forward = lastPageRequested; + backward = lastPageRequested - 1; + } + if (forward < m_doc->pageCount()) { + if (!m_pageCache.contains(forward)) + insertPage(forward); + done = false; + } + if (backward >= 0) { + if (!m_pageCache.contains(backward)) + insertPage(backward); + done = false; + } + ++forward; + --backward; + if (done) + return; + } +} + +void PageCache::insertPage(int page) +{ + if (!m_pageCache.contains(page)) { + QSizeF size = m_doc->pageSize(page) * m_zoom; + QElapsedTimer timer; timer.start(); + const QImage &img = m_doc->render(page, size); + 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; + m_pageCache.insert(page, QPixmap::fromImage(img)); + emit pageReady(page); + + 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/pagecache.h b/examples/widgets/pdfviewer/pagecache.h new file mode 100644 index 000000000..49d8bf8e7 --- /dev/null +++ b/examples/widgets/pdfviewer/pagecache.h @@ -0,0 +1,46 @@ +#ifndef PAGECACHE_H +#define PAGECACHE_H + +#include +#include +#include +#include + +class QPdfDocument; + +class PageCache : public QObject +{ + Q_OBJECT +public: + PageCache(QPdfDocument *doc, qreal zoom); + ~PageCache(); + + QPixmap get(int page); + +public slots: + void run(); + +signals: + void pagesNeeded(); + void pageReady(int page); + +private: + void insertPage(int page); + +private: + QThread *m_thread; + QPdfDocument *m_doc; + QHash m_pageCache; + qreal m_zoom; + int m_lastPageRequested; + QPixmap m_placeholderIcon; + QBrush m_placeholderBackground; + + // 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 index babcd85e6..40569156d 100644 --- a/examples/widgets/pdfviewer/pdfviewer.pro +++ b/examples/widgets/pdfviewer/pdfviewer.pro @@ -4,10 +4,12 @@ TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ - sequentialpagewidget.cpp + sequentialpagewidget.cpp \ + pagecache.cpp HEADERS += mainwindow.h \ - sequentialpagewidget.h + sequentialpagewidget.h \ + pagecache.h FORMS += mainwindow.ui diff --git a/examples/widgets/pdfviewer/resources.qrc b/examples/widgets/pdfviewer/resources.qrc index 945c59565..02d9655b4 100644 --- a/examples/widgets/pdfviewer/resources.qrc +++ b/examples/widgets/pdfviewer/resources.qrc @@ -7,5 +7,6 @@ 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 index 5bac32c61..6b84015b9 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -1,4 +1,5 @@ #include "sequentialpagewidget.h" +#include "pagecache.h" #include #include #include @@ -12,15 +13,12 @@ Q_DECLARE_LOGGING_CATEGORY(lcExample) SequentialPageWidget::SequentialPageWidget(QWidget *parent) : QWidget(parent) , m_doc(Q_NULLPTR) + , m_pageCache(Q_NULLPTR) , m_background(Qt::darkGray) , m_pageSpacing(3) , m_topPageShowing(0) , m_zoom(1.) , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) - , m_minRenderTime(1000000000.) - , m_maxRenderTime(0.) - , m_totalRenderTime(0.) - , m_totalPagesRendered(0) { } @@ -32,6 +30,10 @@ void SequentialPageWidget::setDocument(QPdfDocument *doc) { m_doc = doc; m_topPageShowing = 0; + if (m_pageCache) + delete m_pageCache; + m_pageCache = new PageCache(doc, m_screenResolution * m_zoom); + connect(m_pageCache, SIGNAL(pageReady(int)), this, SLOT(update())); invalidate(); } @@ -49,7 +51,11 @@ QSizeF SequentialPageWidget::pageSize(int page) void SequentialPageWidget::invalidate() { - m_pageCache.clear(); + if (m_pageCache) + delete m_pageCache; + if (m_doc) + m_pageCache = new PageCache(m_doc, m_screenResolution * m_zoom); + connect(m_pageCache, SIGNAL(pageReady(int)), this, SLOT(update())); QSizeF totalSize(0, m_pageSpacing); for (int page = 0; page < m_doc->pageCount(); ++page) { QSizeF size = pageSize(page); @@ -88,36 +94,17 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) } y += m_pageSpacing; m_topPageShowing = page; - int previousRendered = m_totalPagesRendered; + if (!m_pageCache) return; // Actually render pages while (y < event->rect().bottom() && page < m_doc->pageCount()) { - if (!m_pageCache.contains(page)) { - QSizeF size = pageSize(page); - qCDebug(lcExample) << "rendering page" << page << "to size" << size; - QElapsedTimer timer; timer.start(); - const QImage &img = m_doc->render(page, size); - 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; - m_pageCache.insert(page, QPixmap::fromImage(img)); - } - const QPixmap &pm = m_pageCache[page]; + const QPixmap &pm = m_pageCache->get(page); painter.drawPixmap((width() - pm.width()) / 2, y, pm); y += pm.height() + m_pageSpacing; ++page; } m_bottomPageShowing = page - 1; emit showingPageRange(m_topPageShowing, m_bottomPageShowing); - - if (m_totalPagesRendered != previousRendered) - qCDebug(lcExample) << "rendering time: min" << m_minRenderTime << - "avg" << m_totalRenderTime / m_totalPagesRendered << - "max" << m_maxRenderTime; } qreal SequentialPageWidget::yForPage(int endPage) diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 3d91279cf..23dfe7fba 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -4,6 +4,7 @@ #include class QPdfDocument; +class PageCache; class SequentialPageWidget : public QWidget { @@ -33,7 +34,7 @@ private: private: QPdfDocument *m_doc; - QHash m_pageCache; + PageCache *m_pageCache; QBrush m_background; int m_pageSpacing; int m_topPageShowing; @@ -41,12 +42,6 @@ private: QSize m_totalSize; qreal m_zoom; qreal m_screenResolution; // pixels per point - - // performance statistics - qreal m_minRenderTime; - qreal m_maxRenderTime; - qreal m_totalRenderTime; - int m_totalPagesRendered; }; #endif // SEQUENTIALPAGEWIDGET_H -- cgit v1.2.3 From eb91828f3d6f34e6f1b38001b435670ad333d8dc Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 21:20:12 +0100 Subject: pdfviewer example: direct inheritance from QThread But either way, the UI is not as responsive as one could wish for during background rendering. --- examples/widgets/pdfviewer/pagecache.cpp | 11 +++-------- examples/widgets/pdfviewer/pagecache.h | 8 +++++--- 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/pagecache.cpp b/examples/widgets/pdfviewer/pagecache.cpp index 5943b90c2..589a7b09a 100644 --- a/examples/widgets/pdfviewer/pagecache.cpp +++ b/examples/widgets/pdfviewer/pagecache.cpp @@ -3,13 +3,11 @@ #include #include #include -#include Q_DECLARE_LOGGING_CATEGORY(lcExample) PageCache::PageCache(QPdfDocument *doc, qreal zoom) - : QObject(Q_NULLPTR) - , m_thread(new QThread(this)) + : QThread(Q_NULLPTR) , m_doc(doc) , m_zoom(zoom) , m_placeholderIcon(":icons/images/busy.png") @@ -19,8 +17,6 @@ PageCache::PageCache(QPdfDocument *doc, qreal zoom) , m_totalRenderTime(0.) , m_totalPagesRendered(0) { - moveToThread(m_thread); - connect(this, &PageCache::pagesNeeded, this, &PageCache::run, Qt::QueuedConnection); } PageCache::~PageCache() @@ -36,9 +32,8 @@ QPixmap PageCache::get(int page) m_lastPageRequested = page; if (m_pageCache.contains(page)) return m_pageCache[page]; - if (!m_thread->isRunning()) - m_thread->start(QThread::LowestPriority); - emit pagesNeeded(); + if (!isRunning()) + start(QThread::LowestPriority); QSizeF sizeF = m_doc->pageSize(page); if (!sizeF.isValid()) return QPixmap(); diff --git a/examples/widgets/pdfviewer/pagecache.h b/examples/widgets/pdfviewer/pagecache.h index 49d8bf8e7..6d93211dc 100644 --- a/examples/widgets/pdfviewer/pagecache.h +++ b/examples/widgets/pdfviewer/pagecache.h @@ -5,10 +5,11 @@ #include #include #include +#include class QPdfDocument; -class PageCache : public QObject +class PageCache : public QThread { Q_OBJECT public: @@ -21,14 +22,15 @@ public slots: void run(); signals: - void pagesNeeded(); void pageReady(int page); +protected: + Q_DECL_OVERRIDE void run(); + private: void insertPage(int page); private: - QThread *m_thread; QPdfDocument *m_doc; QHash m_pageCache; qreal m_zoom; -- cgit v1.2.3 From e1f46f83389fb3c972edb4240cd5c97b5ff9bcd4 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 16 Dec 2014 00:06:59 +0100 Subject: Fix compilation --- examples/widgets/pdfviewer/pagecache.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/pagecache.h b/examples/widgets/pdfviewer/pagecache.h index 6d93211dc..b1a1a9371 100644 --- a/examples/widgets/pdfviewer/pagecache.h +++ b/examples/widgets/pdfviewer/pagecache.h @@ -18,9 +18,6 @@ public: QPixmap get(int page); -public slots: - void run(); - signals: void pageReady(int page); -- cgit v1.2.3 From c45ac7a4db5fcdab830e29e596bd2c07a0fab5f8 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 22:23:09 +0100 Subject: pdfviewer example: stop creating placeholder images in PageCache --- examples/widgets/pdfviewer/pagecache.cpp | 17 ++--------------- examples/widgets/pdfviewer/pagecache.h | 2 -- examples/widgets/pdfviewer/sequentialpagewidget.cpp | 11 ++++++++++- examples/widgets/pdfviewer/sequentialpagewidget.h | 2 ++ 4 files changed, 14 insertions(+), 18 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/pagecache.cpp b/examples/widgets/pdfviewer/pagecache.cpp index 589a7b09a..293b2d4c3 100644 --- a/examples/widgets/pdfviewer/pagecache.cpp +++ b/examples/widgets/pdfviewer/pagecache.cpp @@ -10,8 +10,6 @@ PageCache::PageCache(QPdfDocument *doc, qreal zoom) : QThread(Q_NULLPTR) , m_doc(doc) , m_zoom(zoom) - , m_placeholderIcon(":icons/images/busy.png") - , m_placeholderBackground(Qt::white) , m_minRenderTime(1000000000.) , m_maxRenderTime(0.) , m_totalRenderTime(0.) @@ -25,7 +23,7 @@ PageCache::~PageCache() /*! Get the result from the cache, - or a placeholder pixmap if unavailable. + or an invalid pixmap if unavailable. */ QPixmap PageCache::get(int page) { @@ -34,18 +32,7 @@ QPixmap PageCache::get(int page) return m_pageCache[page]; if (!isRunning()) start(QThread::LowestPriority); - QSizeF sizeF = m_doc->pageSize(page); - if (!sizeF.isValid()) - return QPixmap(); - QSize size = QSizeF(sizeF * m_zoom).toSize(); - QPixmap placeholder(size); - { - QPainter painter(&placeholder); - painter.fillRect(QRect(QPoint(), size), m_placeholderBackground); - painter.drawPixmap((size.width() - m_placeholderIcon.width()) / 2, - (size.height() - m_placeholderIcon.height()) / 2, m_placeholderIcon); - } - return placeholder; + return QPixmap(); } void PageCache::run() diff --git a/examples/widgets/pdfviewer/pagecache.h b/examples/widgets/pdfviewer/pagecache.h index b1a1a9371..b2c063fae 100644 --- a/examples/widgets/pdfviewer/pagecache.h +++ b/examples/widgets/pdfviewer/pagecache.h @@ -32,8 +32,6 @@ private: QHash m_pageCache; qreal m_zoom; int m_lastPageRequested; - QPixmap m_placeholderIcon; - QBrush m_placeholderBackground; // performance statistics qreal m_minRenderTime; diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index 6b84015b9..da880be2e 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -16,6 +16,8 @@ SequentialPageWidget::SequentialPageWidget(QWidget *parent) , m_pageCache(Q_NULLPTR) , m_background(Qt::darkGray) , m_pageSpacing(3) + , m_placeholderIcon(":icons/images/busy.png") + , m_placeholderBackground(Qt::white) , m_topPageShowing(0) , m_zoom(1.) , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) @@ -99,7 +101,14 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) // Actually render pages while (y < event->rect().bottom() && page < m_doc->pageCount()) { const QPixmap &pm = m_pageCache->get(page); - painter.drawPixmap((width() - pm.width()) / 2, y, pm); + if (pm.isNull()) { + QSizeF size = pageSize(page); + 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); + } else { + painter.drawPixmap((width() - pm.width()) / 2, y, pm); + } y += pm.height() + m_pageSpacing; ++page; } diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 23dfe7fba..3d2c70d2f 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -36,6 +36,8 @@ private: QPdfDocument *m_doc; PageCache *m_pageCache; QBrush m_background; + QPixmap m_placeholderIcon; + QBrush m_placeholderBackground; int m_pageSpacing; int m_topPageShowing; int m_bottomPageShowing; -- cgit v1.2.3 From aa2955dfb064149e57d407671011b551c8d28be2 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Dec 2014 22:30:01 +0100 Subject: pdfviewer example: PageRenderer owns document and thread. Smooth PageCache renamed to PageRenderer and minimized to just being a worker thread. The UI is finally responsive, biecause the locking in QPdfDocument is isolated behind PageRenderer. ATM only renders visible pages though. --- examples/widgets/pdfviewer/mainwindow.cpp | 6 +- examples/widgets/pdfviewer/pagecache.cpp | 88 ---------------------- examples/widgets/pdfviewer/pagecache.h | 43 ----------- examples/widgets/pdfviewer/pagerenderer.cpp | 72 ++++++++++++++++++ examples/widgets/pdfviewer/pagerenderer.h | 46 +++++++++++ examples/widgets/pdfviewer/pdfviewer.pro | 4 +- .../widgets/pdfviewer/sequentialpagewidget.cpp | 74 ++++++++++-------- examples/widgets/pdfviewer/sequentialpagewidget.h | 13 +++- 8 files changed, 171 insertions(+), 175 deletions(-) delete mode 100644 examples/widgets/pdfviewer/pagecache.cpp delete mode 100644 examples/widgets/pdfviewer/pagecache.h create mode 100644 examples/widgets/pdfviewer/pagerenderer.cpp create mode 100644 examples/widgets/pdfviewer/pagerenderer.h (limited to 'examples') diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index df0c5a366..71b35eff6 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -15,13 +15,11 @@ Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer") MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) - , m_doc(new QPdfDocument(this)) , m_pageWidget(new SequentialPageWidget(this)) , m_zoomEdit(new QLineEdit(this)) , m_pageEdit(new QLineEdit(this)) { ui->setupUi(this); - m_pageWidget->setDocument(m_doc); ui->scrollArea->setWidget(m_pageWidget); m_zoomEdit->setMaximumWidth(50); m_zoomEdit->setAlignment(Qt::AlignHCenter); @@ -45,13 +43,11 @@ MainWindow::~MainWindow() void MainWindow::open(const QUrl &docLocation) { if (docLocation.isLocalFile()) - m_doc->load(docLocation.toLocalFile()); + m_pageWidget->openDocument(docLocation); 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())); } - // TODO: connect to signal from document - m_pageWidget->invalidate(); qCDebug(lcExample) << docLocation; ui->scrollArea->ensureVisible(0, 0, 0, 0); } diff --git a/examples/widgets/pdfviewer/pagecache.cpp b/examples/widgets/pdfviewer/pagecache.cpp deleted file mode 100644 index 293b2d4c3..000000000 --- a/examples/widgets/pdfviewer/pagecache.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "pagecache.h" -#include -#include -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(lcExample) - -PageCache::PageCache(QPdfDocument *doc, qreal zoom) - : QThread(Q_NULLPTR) - , m_doc(doc) - , m_zoom(zoom) - , m_minRenderTime(1000000000.) - , m_maxRenderTime(0.) - , m_totalRenderTime(0.) - , m_totalPagesRendered(0) -{ -} - -PageCache::~PageCache() -{ -} - -/*! - Get the result from the cache, - or an invalid pixmap if unavailable. - */ -QPixmap PageCache::get(int page) -{ - m_lastPageRequested = page; - if (m_pageCache.contains(page)) - return m_pageCache[page]; - if (!isRunning()) - start(QThread::LowestPriority); - return QPixmap(); -} - -void PageCache::run() -{ - int lastPageRequested = m_lastPageRequested; - int forward = lastPageRequested; - int backward = lastPageRequested - 1; - while (true) { - bool done = true; - if (lastPageRequested != m_lastPageRequested) { - lastPageRequested = m_lastPageRequested; - forward = lastPageRequested; - backward = lastPageRequested - 1; - } - if (forward < m_doc->pageCount()) { - if (!m_pageCache.contains(forward)) - insertPage(forward); - done = false; - } - if (backward >= 0) { - if (!m_pageCache.contains(backward)) - insertPage(backward); - done = false; - } - ++forward; - --backward; - if (done) - return; - } -} - -void PageCache::insertPage(int page) -{ - if (!m_pageCache.contains(page)) { - QSizeF size = m_doc->pageSize(page) * m_zoom; - QElapsedTimer timer; timer.start(); - const QImage &img = m_doc->render(page, size); - 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; - m_pageCache.insert(page, QPixmap::fromImage(img)); - emit pageReady(page); - - 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/pagecache.h b/examples/widgets/pdfviewer/pagecache.h deleted file mode 100644 index b2c063fae..000000000 --- a/examples/widgets/pdfviewer/pagecache.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef PAGECACHE_H -#define PAGECACHE_H - -#include -#include -#include -#include -#include - -class QPdfDocument; - -class PageCache : public QThread -{ - Q_OBJECT -public: - PageCache(QPdfDocument *doc, qreal zoom); - ~PageCache(); - - QPixmap get(int page); - -signals: - void pageReady(int page); - -protected: - Q_DECL_OVERRIDE void run(); - -private: - void insertPage(int page); - -private: - QPdfDocument *m_doc; - QHash m_pageCache; - qreal m_zoom; - int m_lastPageRequested; - - // performance statistics - qreal m_minRenderTime; - qreal m_maxRenderTime; - qreal m_totalRenderTime; - int m_totalPagesRendered; -}; - -#endif // PAGECACHE_H diff --git a/examples/widgets/pdfviewer/pagerenderer.cpp b/examples/widgets/pdfviewer/pagerenderer.cpp new file mode 100644 index 000000000..88316498e --- /dev/null +++ b/examples/widgets/pdfviewer/pagerenderer.cpp @@ -0,0 +1,72 @@ +#include "pagerenderer.h" +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(lcExample) + +PageRenderer::PageRenderer() + : QThread(Q_NULLPTR) + , m_doc(new QPdfDocument(this)) + , m_page(0) + , m_zoom(1.) + , m_minRenderTime(1000000000.) + , m_maxRenderTime(0.) + , m_totalRenderTime(0.) + , m_totalPagesRendered(0) +{ +} + +PageRenderer::~PageRenderer() +{ +} + +QVector PageRenderer::openDocument(const QUrl &location) +{ + if (location.isLocalFile()) + m_doc->load(location.toLocalFile()); + else { + qCWarning(lcExample, "non-local file loading is not implemented"); + return QVector(); + } + // TODO maybe do in run() if it takes too long + QVector pageSizes; + for (int page = 0; page < m_doc->pageCount(); ++page) + pageSizes.append(m_doc->pageSize(page)); + return pageSizes; +} + +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) +{ + QSizeF size = m_doc->pageSize(page) * m_zoom; + QElapsedTimer timer; timer.start(); + const QImage &img = m_doc->render(page, size); + 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 new file mode 100644 index 000000000..f121b6aa8 --- /dev/null +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -0,0 +1,46 @@ +#ifndef PAGECACHE_H +#define PAGECACHE_H + +#include +#include +#include +#include +#include + +class QPdfDocument; + +class PageRenderer : public QThread +{ + Q_OBJECT +public: + PageRenderer(); + ~PageRenderer(); + +public slots: + QVector openDocument(const QUrl &location); + void requestPage(int page, qreal zoom, Priority priority = QThread::NormalPriority); + +signals: + void pageReady(int page, qreal zoom, QImage image); + +protected: + Q_DECL_OVERRIDE void run(); + +private: + void renderPage(int page, qreal zoom); + +private: + QPdfDocument *m_doc; + + // 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 index 40569156d..e8269c41a 100644 --- a/examples/widgets/pdfviewer/pdfviewer.pro +++ b/examples/widgets/pdfviewer/pdfviewer.pro @@ -5,11 +5,11 @@ TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ sequentialpagewidget.cpp \ - pagecache.cpp + pagerenderer.cpp HEADERS += mainwindow.h \ sequentialpagewidget.h \ - pagecache.h + pagerenderer.h FORMS += mainwindow.ui diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index da880be2e..2f4e3fb68 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -1,5 +1,5 @@ #include "sequentialpagewidget.h" -#include "pagecache.h" +#include "pagerenderer.h" #include #include #include @@ -12,30 +12,27 @@ Q_DECLARE_LOGGING_CATEGORY(lcExample) SequentialPageWidget::SequentialPageWidget(QWidget *parent) : QWidget(parent) - , m_doc(Q_NULLPTR) - , m_pageCache(Q_NULLPTR) + , m_pageRenderer(new PageRenderer()) , m_background(Qt::darkGray) - , m_pageSpacing(3) , 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) { + connect(m_pageRenderer, SIGNAL(pageReady(int, qreal, QImage)), this, SLOT(pageLoaded(int, qreal, QImage)), Qt::QueuedConnection); } SequentialPageWidget::~SequentialPageWidget() { + delete m_pageRenderer; } -void SequentialPageWidget::setDocument(QPdfDocument *doc) +void SequentialPageWidget::openDocument(const QUrl &url) { - m_doc = doc; + m_pageSizes = m_pageRenderer->openDocument(url); m_topPageShowing = 0; - if (m_pageCache) - delete m_pageCache; - m_pageCache = new PageCache(doc, m_screenResolution * m_zoom); - connect(m_pageCache, SIGNAL(pageReady(int)), this, SLOT(update())); invalidate(); } @@ -48,20 +45,19 @@ void SequentialPageWidget::setZoom(qreal factor) QSizeF SequentialPageWidget::pageSize(int page) { - return m_doc->pageSize(page) * m_screenResolution * m_zoom; +// if (!m_pageSizes.length() <= page) +// return QSizeF(); + return m_pageSizes[page] * m_screenResolution * m_zoom; } void SequentialPageWidget::invalidate() { - if (m_pageCache) - delete m_pageCache; - if (m_doc) - m_pageCache = new PageCache(m_doc, m_screenResolution * m_zoom); - connect(m_pageCache, SIGNAL(pageReady(int)), this, SLOT(update())); QSizeF totalSize(0, m_pageSpacing); - for (int page = 0; page < m_doc->pageCount(); ++page) { +qDebug() << "pageCount" << pageCount(); + + for (int page = 0; page < pageCount(); ++page) { QSizeF size = pageSize(page); - qDebug() << "page" << page << "size" << size; + qDebug() << "page" << page << "size" << size << "from" << m_pageSizes[page]; totalSize.setHeight(totalSize.height() + size.height()); if (size.width() > totalSize.width()) totalSize.setWidth(size.width()); @@ -73,20 +69,30 @@ void SequentialPageWidget::invalidate() update(); } +void SequentialPageWidget::pageLoaded(int page, qreal zoom, QImage image) +{ + Q_UNUSED(zoom) + m_pageCache.insert(page, image); + update(); +} + +int SequentialPageWidget::pageCount() +{ + return m_pageSizes.count(); +} + void SequentialPageWidget::paintEvent(QPaintEvent * event) { QPainter painter(this); - if (!m_doc) { - painter.drawText(rect(), Qt::AlignCenter, tr("no document loaded")); - return; - } - 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 < m_doc->pageCount()) { + while (page < pageCount()) { QSizeF size = pageSize(page); int height = size.toSize().height(); if (y + height >= event->rect().top()) @@ -96,20 +102,22 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) } y += m_pageSpacing; m_topPageShowing = page; - if (!m_pageCache) return; + +qDebug() << y << m_topPageShowing << pageCount(); // Actually render pages - while (y < event->rect().bottom() && page < m_doc->pageCount()) { - const QPixmap &pm = m_pageCache->get(page); - if (pm.isNull()) { - QSizeF size = pageSize(page); + while (y < event->rect().bottom() && page < pageCount()) { + QSizeF size = pageSize(page); + if (m_pageCache.contains(page)) { + const QImage &img = m_pageCache[page]; + 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); - } else { - painter.drawPixmap((width() - pm.width()) / 2, y, pm); + m_pageRenderer->requestPage(page, m_screenResolution * m_zoom); } - y += pm.height() + m_pageSpacing; + y += size.height() + m_pageSpacing; ++page; } m_bottomPageShowing = page - 1; @@ -120,7 +128,7 @@ qreal SequentialPageWidget::yForPage(int endPage) { // TODO maybe put this loop into a page iterator class int y = m_pageSpacing; - for (int page = 0; page < m_doc->pageCount() && page < endPage; ++page) { + for (int page = 0; page < pageCount() && page < endPage; ++page) { QSizeF size = pageSize(page); int height = size.toSize().height(); y += height + m_pageSpacing; diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 3d2c70d2f..2a3025d29 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -4,7 +4,7 @@ #include class QPdfDocument; -class PageCache; +class PageRenderer; class SequentialPageWidget : public QWidget { @@ -20,7 +20,7 @@ public: int bottomPageShowing() { return m_bottomPageShowing; } public slots: - void setDocument(QPdfDocument *doc); + void openDocument(const QUrl &url); void setZoom(qreal factor); void invalidate(); @@ -28,13 +28,18 @@ signals: void showingPageRange(int start, int end); void zoomChanged(qreal factor); +private slots: + void pageLoaded(int page, qreal zoom, QImage image); + private: + int pageCount(); QSizeF pageSize(int page); void render(int page); private: - QPdfDocument *m_doc; - PageCache *m_pageCache; + QHash m_pageCache; + QVector m_pageSizes; + PageRenderer *m_pageRenderer; QBrush m_background; QPixmap m_placeholderIcon; QBrush m_placeholderBackground; -- cgit v1.2.3 From 2f845dfe45e3d6adbb531952ef00507ddbe9f318 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 16 Dec 2014 00:57:43 +0100 Subject: Fix small memory leak, don't leak the QPdfDocument --- examples/widgets/pdfviewer/mainwindow.h | 2 -- examples/widgets/pdfviewer/pagerenderer.cpp | 10 +++++----- examples/widgets/pdfviewer/pagerenderer.h | 3 ++- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h index 5d638ec33..d49fc50e8 100644 --- a/examples/widgets/pdfviewer/mainwindow.h +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -11,7 +11,6 @@ class MainWindow; } class QLineEdit; -class QPdfDocument; class SequentialPageWidget; class MainWindow : public QMainWindow @@ -43,7 +42,6 @@ private slots: private: Ui::MainWindow *ui; - QPdfDocument *m_doc; SequentialPageWidget *m_pageWidget; QLineEdit *m_zoomEdit; QLineEdit *m_pageEdit; diff --git a/examples/widgets/pdfviewer/pagerenderer.cpp b/examples/widgets/pdfviewer/pagerenderer.cpp index 88316498e..fca4a0f1c 100644 --- a/examples/widgets/pdfviewer/pagerenderer.cpp +++ b/examples/widgets/pdfviewer/pagerenderer.cpp @@ -26,15 +26,15 @@ PageRenderer::~PageRenderer() QVector PageRenderer::openDocument(const QUrl &location) { if (location.isLocalFile()) - m_doc->load(location.toLocalFile()); + m_doc.load(location.toLocalFile()); else { qCWarning(lcExample, "non-local file loading is not implemented"); return QVector(); } // TODO maybe do in run() if it takes too long QVector pageSizes; - for (int page = 0; page < m_doc->pageCount(); ++page) - pageSizes.append(m_doc->pageSize(page)); + for (int page = 0; page < m_doc.pageCount(); ++page) + pageSizes.append(m_doc.pageSize(page)); return pageSizes; } @@ -53,9 +53,9 @@ void PageRenderer::run() void PageRenderer::renderPage(int page, qreal zoom) { - QSizeF size = m_doc->pageSize(page) * m_zoom; + QSizeF size = m_doc.pageSize(page) * m_zoom; QElapsedTimer timer; timer.start(); - const QImage &img = m_doc->render(page, size); + const QImage &img = m_doc.render(page, size); qreal secs = timer.nsecsElapsed() / 1000000000.0; if (secs < m_minRenderTime) m_minRenderTime = secs; diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h index f121b6aa8..7b11e9bed 100644 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -6,6 +6,7 @@ #include #include #include +#include class QPdfDocument; @@ -30,7 +31,7 @@ private: void renderPage(int page, qreal zoom); private: - QPdfDocument *m_doc; + QPdfDocument m_doc; // current request only int m_page; -- cgit v1.2.3 From 3179fdc69841813dcaf529b1553be5be968225ab Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 16 Dec 2014 01:01:41 +0100 Subject: Fix build with MSVC Q_DECL_OVERRIDE comes last in the declaration --- examples/widgets/pdfviewer/pagerenderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h index 7b11e9bed..35c89391e 100644 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -25,7 +25,7 @@ signals: void pageReady(int page, qreal zoom, QImage image); protected: - Q_DECL_OVERRIDE void run(); + void run() Q_DECL_OVERRIDE; private: void renderPage(int page, qreal zoom); -- cgit v1.2.3 From 44a4a350004de012510f9a82353b09b1b3c68884 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 16 Dec 2014 01:37:36 +0100 Subject: pdfviewer example: QScroller makes kinetic flicking work --- examples/widgets/pdfviewer/mainwindow.cpp | 3 +++ examples/widgets/pdfviewer/sequentialpagewidget.cpp | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index 71b35eff6..f3fa00035 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include "sequentialpagewidget.h" @@ -33,6 +34,8 @@ MainWindow::MainWindow(QWidget *parent) 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); } MainWindow::~MainWindow() diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index 2f4e3fb68..c85f784c8 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -53,11 +53,8 @@ QSizeF SequentialPageWidget::pageSize(int page) void SequentialPageWidget::invalidate() { QSizeF totalSize(0, m_pageSpacing); -qDebug() << "pageCount" << pageCount(); - for (int page = 0; page < pageCount(); ++page) { QSizeF size = pageSize(page); - qDebug() << "page" << page << "size" << size << "from" << m_pageSizes[page]; totalSize.setHeight(totalSize.height() + size.height()); if (size.width() > totalSize.width()) totalSize.setWidth(size.width()); @@ -103,8 +100,6 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) y += m_pageSpacing; m_topPageShowing = page; -qDebug() << y << m_topPageShowing << pageCount(); - // Actually render pages while (y < event->rect().bottom() && page < pageCount()) { QSizeF size = pageSize(page); -- cgit v1.2.3 From 598ad60d562832d9b3452ef3bc8fa4a4c84b47e4 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 16 Dec 2014 10:38:06 +0100 Subject: pdfviewer example: page cache has a page count limit to limit memory usage --- examples/widgets/pdfviewer/sequentialpagewidget.cpp | 4 ++++ examples/widgets/pdfviewer/sequentialpagewidget.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index c85f784c8..c5ba65071 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -12,6 +12,7 @@ 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") @@ -69,7 +70,10 @@ void SequentialPageWidget::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(); } diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 2a3025d29..d612e9a7a 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -38,6 +38,8 @@ private: private: QHash m_pageCache; + QList m_cachedPagesLRU; + int m_pageCacheLimit; QVector m_pageSizes; PageRenderer *m_pageRenderer; QBrush m_background; -- cgit v1.2.3 From 41ee275f225af2f5066b79041c56f87ea3d56429 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 16 Dec 2014 11:07:34 +0100 Subject: QScroller doesn't work unless a gesture is grabbed correction to 0108ecad44e04be9d0b60f4b6b7e0fceb69ea034 QScroller was working because of a subsequent patch that tried to add pinch zooming. --- examples/widgets/pdfviewer/sequentialpagewidget.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index c5ba65071..81ab8ccd0 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -23,6 +23,7 @@ SequentialPageWidget::SequentialPageWidget(QWidget *parent) , m_screenResolution(QGuiApplication::primaryScreen()->logicalDotsPerInch() / 72.0) { connect(m_pageRenderer, SIGNAL(pageReady(int, qreal, QImage)), this, SLOT(pageLoaded(int, qreal, QImage)), Qt::QueuedConnection); + grabGesture(Qt::SwipeGesture); } SequentialPageWidget::~SequentialPageWidget() -- cgit v1.2.3 From f1ba6305ca5613ee4b22ad2076da434bbc0526a1 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 22 Jul 2016 13:49:51 +0200 Subject: Add license header boilerplate Commercial until we have figured out the licensing :) Change-Id: Ibf60ca98cf04ee23928794a96ae33f87608c3236 Reviewed-by: Tobias Koenig --- examples/widgets/pdfviewer/main.cpp | 21 +++++++++++++++++++++ examples/widgets/pdfviewer/mainwindow.cpp | 21 +++++++++++++++++++++ examples/widgets/pdfviewer/mainwindow.h | 21 +++++++++++++++++++++ examples/widgets/pdfviewer/pagerenderer.cpp | 21 +++++++++++++++++++++ examples/widgets/pdfviewer/pagerenderer.h | 21 +++++++++++++++++++++ examples/widgets/pdfviewer/sequentialpagewidget.cpp | 21 +++++++++++++++++++++ examples/widgets/pdfviewer/sequentialpagewidget.h | 21 +++++++++++++++++++++ 7 files changed, 147 insertions(+) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/main.cpp b/examples/widgets/pdfviewer/main.cpp index 51a3f9883..d020ade00 100644 --- a/examples/widgets/pdfviewer/main.cpp +++ b/examples/widgets/pdfviewer/main.cpp @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #include "mainwindow.h" #include #include diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index f3fa00035..eacb68b92 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #include "mainwindow.h" #include "ui_mainwindow.h" diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h index d49fc50e8..d3db7a158 100644 --- a/examples/widgets/pdfviewer/mainwindow.h +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #ifndef MAINWINDOW_H #define MAINWINDOW_H diff --git a/examples/widgets/pdfviewer/pagerenderer.cpp b/examples/widgets/pdfviewer/pagerenderer.cpp index fca4a0f1c..33f555334 100644 --- a/examples/widgets/pdfviewer/pagerenderer.cpp +++ b/examples/widgets/pdfviewer/pagerenderer.cpp @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #include "pagerenderer.h" #include #include diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h index 35c89391e..94987c4c6 100644 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #ifndef PAGECACHE_H #define PAGECACHE_H diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index 81ab8ccd0..4107b864a 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #include "sequentialpagewidget.h" #include "pagerenderer.h" #include diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index d612e9a7a..233e5dbee 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -1,3 +1,24 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt PDF Module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + #ifndef SEQUENTIALPAGEWIDGET_H #define SEQUENTIALPAGEWIDGET_H -- cgit v1.2.3 From 7f6080c497859ddde840fae3cea2cfbb0d837a01 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 24 Aug 2016 13:07:25 +0200 Subject: pdfviewer: Fix zooming of content Clear the page cache after zoom level has changed, otherwise the page content won't be rerendered with new zoom level. Change-Id: If374d65570c0ecce3a94d496d57a8e28dcbf8e0a Reviewed-by: Simon Hausmann --- examples/widgets/pdfviewer/sequentialpagewidget.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index 4107b864a..229ba6168 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -86,6 +86,7 @@ void SequentialPageWidget::invalidate() setMinimumSize(m_totalSize); emit zoomChanged(m_zoom); qCDebug(lcExample) << "total size" << m_totalSize; + m_pageCache.clear(); update(); } -- cgit v1.2.3 From 3e3acb3771b2223c0b9ec0cf411d569bd1994ff4 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 24 Aug 2016 13:13:14 +0200 Subject: pdfviewer: Draw white background behind page Change-Id: I50e85b8d135dc4fa93211567d195229cd3892086 Reviewed-by: Simon Hausmann --- examples/widgets/pdfviewer/sequentialpagewidget.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index 229ba6168..f02290a0a 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -132,6 +132,7 @@ void SequentialPageWidget::paintEvent(QPaintEvent * event) 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); -- cgit v1.2.3 From b9f3310cf9f5d2a35c1c97c334931052cee6f932 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 24 Aug 2016 13:34:54 +0200 Subject: pdfviewer: Move QPdfDocument to MainWindow Move the QPdfDocument out of PageRenderer into MainWindow, since the document is needed there to get more information. This patch ignores the locking for now, since QPdfDocument::render() seem to be a read-only action anyway. Change-Id: Idd322bcb87a296a70a04b60984378049e6c4e4fb Reviewed-by: Simon Hausmann --- examples/widgets/pdfviewer/mainwindow.cpp | 14 ++++--- examples/widgets/pdfviewer/mainwindow.h | 7 +++- examples/widgets/pdfviewer/pagerenderer.cpp | 47 ++++++++++------------ examples/widgets/pdfviewer/pagerenderer.h | 15 +++---- .../widgets/pdfviewer/sequentialpagewidget.cpp | 25 ++++++++++-- examples/widgets/pdfviewer/sequentialpagewidget.h | 6 ++- 6 files changed, 68 insertions(+), 46 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index eacb68b92..901e80128 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -22,13 +22,14 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include "sequentialpagewidget.h" + #include #include #include -#include #include +#include #include -#include "sequentialpagewidget.h" const qreal zoomMultiplier = qSqrt(2.0); @@ -40,6 +41,7 @@ MainWindow::MainWindow(QWidget *parent) , 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); @@ -57,6 +59,8 @@ MainWindow::MainWindow(QWidget *parent) connect(m_pageEdit, SIGNAL(returnPressed()), this, SLOT(on_actionGo_triggered())); QScroller::grabGesture(ui->scrollArea); + + m_pageWidget->setDocument(m_document); } MainWindow::~MainWindow() @@ -66,9 +70,9 @@ MainWindow::~MainWindow() void MainWindow::open(const QUrl &docLocation) { - if (docLocation.isLocalFile()) - m_pageWidget->openDocument(docLocation); - else { + 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())); } diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h index d3db7a158..37996b6aa 100644 --- a/examples/widgets/pdfviewer/mainwindow.h +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -22,8 +22,8 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include #include +#include Q_DECLARE_LOGGING_CATEGORY(lcExample) @@ -32,6 +32,7 @@ class MainWindow; } class QLineEdit; +class QPdfDocument; class SequentialPageWidget; class MainWindow : public QMainWindow @@ -39,7 +40,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); public slots: @@ -66,6 +67,8 @@ private: SequentialPageWidget *m_pageWidget; QLineEdit *m_zoomEdit; QLineEdit *m_pageEdit; + + QPdfDocument *m_document; }; #endif // MAINWINDOW_H diff --git a/examples/widgets/pdfviewer/pagerenderer.cpp b/examples/widgets/pdfviewer/pagerenderer.cpp index 33f555334..7a9df635d 100644 --- a/examples/widgets/pdfviewer/pagerenderer.cpp +++ b/examples/widgets/pdfviewer/pagerenderer.cpp @@ -20,17 +20,18 @@ ******************************************************************************/ #include "pagerenderer.h" + +#include +#include #include #include -#include -#include #include Q_DECLARE_LOGGING_CATEGORY(lcExample) -PageRenderer::PageRenderer() - : QThread(Q_NULLPTR) - , m_doc(new QPdfDocument(this)) +PageRenderer::PageRenderer(QObject *parent) + : QThread(parent) + , m_document(nullptr) , m_page(0) , m_zoom(1.) , m_minRenderTime(1000000000.) @@ -40,23 +41,9 @@ PageRenderer::PageRenderer() { } -PageRenderer::~PageRenderer() -{ -} - -QVector PageRenderer::openDocument(const QUrl &location) +void PageRenderer::setDocument(QPdfDocument *document) { - if (location.isLocalFile()) - m_doc.load(location.toLocalFile()); - else { - qCWarning(lcExample, "non-local file loading is not implemented"); - return QVector(); - } - // TODO maybe do in run() if it takes too long - QVector pageSizes; - for (int page = 0; page < m_doc.pageCount(); ++page) - pageSizes.append(m_doc.pageSize(page)); - return pageSizes; + m_document = document; } void PageRenderer::requestPage(int page, qreal zoom, Priority priority) @@ -74,16 +61,26 @@ void PageRenderer::run() void PageRenderer::renderPage(int page, qreal zoom) { - QSizeF size = m_doc.pageSize(page) * m_zoom; - QElapsedTimer timer; timer.start(); - const QImage &img = m_doc.render(page, size); - qreal secs = timer.nsecsElapsed() / 1000000000.0; + 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 << diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h index 94987c4c6..be861a974 100644 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -22,24 +22,21 @@ #ifndef PAGECACHE_H #define PAGECACHE_H -#include -#include -#include -#include +#include #include -#include class QPdfDocument; class PageRenderer : public QThread { Q_OBJECT + public: - PageRenderer(); - ~PageRenderer(); + explicit PageRenderer(QObject *parent = nullptr); public slots: - QVector openDocument(const QUrl &location); + void setDocument(QPdfDocument *document); + void requestPage(int page, qreal zoom, Priority priority = QThread::NormalPriority); signals: @@ -52,7 +49,7 @@ private: void renderPage(int page, qreal zoom); private: - QPdfDocument m_doc; + QPdfDocument *m_document; // current request only int m_page; diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index f02290a0a..b0dcb1e19 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -42,6 +42,7 @@ SequentialPageWidget::SequentialPageWidget(QWidget *parent) , 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); @@ -52,11 +53,14 @@ SequentialPageWidget::~SequentialPageWidget() delete m_pageRenderer; } -void SequentialPageWidget::openDocument(const QUrl &url) +void SequentialPageWidget::setDocument(QPdfDocument *document) { - m_pageSizes = m_pageRenderer->openDocument(url); - m_topPageShowing = 0; - invalidate(); + m_pageRenderer->setDocument(document); + + m_document = document; + connect(m_document, &QPdfDocument::statusChanged, this, &SequentialPageWidget::documentStatusChanged); + + documentStatusChanged(); } void SequentialPageWidget::setZoom(qreal factor) @@ -90,6 +94,19 @@ void SequentialPageWidget::invalidate() 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) diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 233e5dbee..ca45fe4c1 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -40,8 +40,9 @@ public: int topPageShowing() { return m_topPageShowing; } int bottomPageShowing() { return m_bottomPageShowing; } + void setDocument(QPdfDocument *document); + public slots: - void openDocument(const QUrl &url); void setZoom(qreal factor); void invalidate(); @@ -50,6 +51,7 @@ signals: void zoomChanged(qreal factor); private slots: + void documentStatusChanged(); void pageLoaded(int page, qreal zoom, QImage image); private: @@ -72,6 +74,8 @@ private: QSize m_totalSize; qreal m_zoom; qreal m_screenResolution; // pixels per point + + QPdfDocument *m_document; }; #endif // SEQUENTIALPAGEWIDGET_H -- cgit v1.2.3 From b2b7503192cb6cb2f0c97a76a5320f710d2d6568 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 15 Dec 2016 19:36:54 +0100 Subject: replace Q_NULLPTR and Q_DECL_OVERRIDE Change-Id: Icf33776f70bdde71f320de0a129361ac28fd18c8 Reviewed-by: Tobias Koenig --- examples/widgets/pdfviewer/pagerenderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h index be861a974..2e884eed2 100644 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -43,7 +43,7 @@ signals: void pageReady(int page, qreal zoom, QImage image); protected: - void run() Q_DECL_OVERRIDE; + void run() override; private: void renderPage(int page, qreal zoom); -- cgit v1.2.3 From 3c085d95d01165f194a480834ed9953ff1d88f5c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 15 Dec 2016 19:41:07 +0100 Subject: example: QVector instead of QList Change-Id: I8610d9962298c65358e3d16403208eca4e2060c7 Reviewed-by: Tobias Koenig Reviewed-by: Simon Hausmann --- examples/widgets/pdfviewer/sequentialpagewidget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index ca45fe4c1..5a756d1c6 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -61,7 +61,7 @@ private: private: QHash m_pageCache; - QList m_cachedPagesLRU; + QVector m_cachedPagesLRU; int m_pageCacheLimit; QVector m_pageSizes; PageRenderer *m_pageRenderer; -- cgit v1.2.3 From 34f81299d8655c637526dcd0dfe522b72c58f1a0 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 25 Aug 2016 12:06:04 +0200 Subject: change the license to LGPLv3 (with the commercial option) Change-Id: I2caed38ece8067ecdad877dcc278f7828a3cb0bb Reviewed-by: Lars Knoll Reviewed-by: Frederik Gladhorn --- examples/widgets/pdfviewer/main.cpp | 27 +++++++++++++++++----- examples/widgets/pdfviewer/mainwindow.cpp | 27 +++++++++++++++++----- examples/widgets/pdfviewer/mainwindow.h | 27 +++++++++++++++++----- examples/widgets/pdfviewer/pagerenderer.cpp | 27 +++++++++++++++++----- examples/widgets/pdfviewer/pagerenderer.h | 27 +++++++++++++++++----- .../widgets/pdfviewer/sequentialpagewidget.cpp | 27 +++++++++++++++++----- examples/widgets/pdfviewer/sequentialpagewidget.h | 27 +++++++++++++++++----- 7 files changed, 147 insertions(+), 42 deletions(-) (limited to 'examples') diff --git a/examples/widgets/pdfviewer/main.cpp b/examples/widgets/pdfviewer/main.cpp index d020ade00..20fa6f8cd 100644 --- a/examples/widgets/pdfviewer/main.cpp +++ b/examples/widgets/pdfviewer/main.cpp @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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 diff --git a/examples/widgets/pdfviewer/mainwindow.cpp b/examples/widgets/pdfviewer/mainwindow.cpp index 901e80128..d865a8bdd 100644 --- a/examples/widgets/pdfviewer/mainwindow.cpp +++ b/examples/widgets/pdfviewer/mainwindow.cpp @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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" diff --git a/examples/widgets/pdfviewer/mainwindow.h b/examples/widgets/pdfviewer/mainwindow.h index 37996b6aa..dedc81267 100644 --- a/examples/widgets/pdfviewer/mainwindow.h +++ b/examples/widgets/pdfviewer/mainwindow.h @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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 diff --git a/examples/widgets/pdfviewer/pagerenderer.cpp b/examples/widgets/pdfviewer/pagerenderer.cpp index 7a9df635d..c8f245640 100644 --- a/examples/widgets/pdfviewer/pagerenderer.cpp +++ b/examples/widgets/pdfviewer/pagerenderer.cpp @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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" diff --git a/examples/widgets/pdfviewer/pagerenderer.h b/examples/widgets/pdfviewer/pagerenderer.h index 2e884eed2..5feccaac6 100644 --- a/examples/widgets/pdfviewer/pagerenderer.h +++ b/examples/widgets/pdfviewer/pagerenderer.h @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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 diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp index b0dcb1e19..904bc17d2 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.cpp +++ b/examples/widgets/pdfviewer/sequentialpagewidget.cpp @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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" diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.h b/examples/widgets/pdfviewer/sequentialpagewidget.h index 5a756d1c6..85f35713c 100644 --- a/examples/widgets/pdfviewer/sequentialpagewidget.h +++ b/examples/widgets/pdfviewer/sequentialpagewidget.h @@ -1,12 +1,11 @@ -/****************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt PDF Module. -** -** $QT_BEGIN_LICENSE:COMM$ +** 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 @@ -15,9 +14,25 @@ ** 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 -- cgit v1.2.3 From f8d12697a3830d331589229aec6d83e6686f77fc 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/pdfwidgets/pdfviewer/images/busy.png | Bin 0 -> 172 bytes examples/pdfwidgets/pdfviewer/images/fileopen.png | Bin 0 -> 1771 bytes .../pdfwidgets/pdfviewer/images/go-next-24.png | Bin 0 -> 782 bytes .../pdfwidgets/pdfviewer/images/go-previous-24.png | Bin 0 -> 797 bytes .../pdfwidgets/pdfviewer/images/zoom-in-24.png | Bin 0 -> 1302 bytes .../pdfwidgets/pdfviewer/images/zoom-in-32.png | Bin 0 -> 1873 bytes .../pdfwidgets/pdfviewer/images/zoom-out-24.png | Bin 0 -> 1247 bytes .../pdfwidgets/pdfviewer/images/zoom-out-32.png | Bin 0 -> 1749 bytes examples/pdfwidgets/pdfviewer/main.cpp | 51 ++++++ examples/pdfwidgets/pdfviewer/mainwindow.cpp | 170 ++++++++++++++++++ examples/pdfwidgets/pdfviewer/mainwindow.h | 89 ++++++++++ examples/pdfwidgets/pdfviewer/mainwindow.ui | 173 +++++++++++++++++++ examples/pdfwidgets/pdfviewer/pagerenderer.cpp | 105 +++++++++++ examples/pdfwidgets/pdfviewer/pagerenderer.h | 80 +++++++++ examples/pdfwidgets/pdfviewer/pdfviewer.pro | 21 +++ examples/pdfwidgets/pdfviewer/resources.qrc | 12 ++ .../pdfwidgets/pdfviewer/sequentialpagewidget.cpp | 192 +++++++++++++++++++++ .../pdfwidgets/pdfviewer/sequentialpagewidget.h | 96 +++++++++++ examples/pdfwidgets/pdfwidgets.pro | 2 + 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 ----------- 37 files changed, 991 insertions(+), 985 deletions(-) create mode 100644 examples/pdfwidgets/pdfviewer/images/busy.png create mode 100644 examples/pdfwidgets/pdfviewer/images/fileopen.png create mode 100644 examples/pdfwidgets/pdfviewer/images/go-next-24.png create mode 100644 examples/pdfwidgets/pdfviewer/images/go-previous-24.png create mode 100644 examples/pdfwidgets/pdfviewer/images/zoom-in-24.png create mode 100644 examples/pdfwidgets/pdfviewer/images/zoom-in-32.png create mode 100644 examples/pdfwidgets/pdfviewer/images/zoom-out-24.png create mode 100644 examples/pdfwidgets/pdfviewer/images/zoom-out-32.png create mode 100644 examples/pdfwidgets/pdfviewer/main.cpp create mode 100644 examples/pdfwidgets/pdfviewer/mainwindow.cpp create mode 100644 examples/pdfwidgets/pdfviewer/mainwindow.h create mode 100644 examples/pdfwidgets/pdfviewer/mainwindow.ui create mode 100644 examples/pdfwidgets/pdfviewer/pagerenderer.cpp create mode 100644 examples/pdfwidgets/pdfviewer/pagerenderer.h create mode 100644 examples/pdfwidgets/pdfviewer/pdfviewer.pro create mode 100644 examples/pdfwidgets/pdfviewer/resources.qrc create mode 100644 examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp create mode 100644 examples/pdfwidgets/pdfviewer/sequentialpagewidget.h create mode 100644 examples/pdfwidgets/pdfwidgets.pro 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 (limited to 'examples') diff --git a/examples/pdfwidgets/pdfviewer/images/busy.png b/examples/pdfwidgets/pdfviewer/images/busy.png new file mode 100644 index 000000000..69056c479 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/busy.png differ diff --git a/examples/pdfwidgets/pdfviewer/images/fileopen.png b/examples/pdfwidgets/pdfviewer/images/fileopen.png new file mode 100644 index 000000000..33e0d6394 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/fileopen.png 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 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/go-next-24.png 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 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/go-previous-24.png 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 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png 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 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png 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 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png 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 Binary files /dev/null and b/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png 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 +#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/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 +#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/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 +#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/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 @@ + + + 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/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 +#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/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 +#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/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 @@ + + + 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/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 +#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/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 + +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/pdfwidgets/pdfwidgets.pro b/examples/pdfwidgets/pdfwidgets.pro new file mode 100644 index 000000000..a12dc5b86 --- /dev/null +++ b/examples/pdfwidgets/pdfwidgets.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += pdfviewer diff --git a/examples/widgets/pdfviewer/images/busy.png b/examples/widgets/pdfviewer/images/busy.png deleted file mode 100644 index 69056c479..000000000 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 33e0d6394..000000000 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 9a55ef3d8..000000000 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 2ea769eb8..000000000 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 d29b142b6..000000000 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 34d70af37..000000000 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 19703474f..000000000 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 b83220661..000000000 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 20fa6f8cd..000000000 --- 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 d865a8bdd..000000000 --- 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 dedc81267..000000000 --- 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 7070619b9..000000000 --- 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 c8f245640..000000000 --- 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 5feccaac6..000000000 --- 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 e8269c41a..000000000 --- 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 02d9655b4..000000000 --- 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 904bc17d2..000000000 --- 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 85f35713c..000000000 --- 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 From 0f07c791c64c7f914bd07be70dbbf50501c862f4 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 30 Jan 2017 04:45:57 -0800 Subject: Improve the PDF viewer example aesthetics Sets the window title as the title of the PDF document, enlarges the default window size, uses unified toolbars on macOS, extends the viewer area to the edges of the containing window, and removes the Windows 95 style shrunken frame around the PDF viewer. Change-Id: I38753a2b5492ac0cc0d2a11ae62011ac595a0e70 Reviewed-by: Shawn Rutledge Reviewed-by: Tobias Koenig --- examples/pdfwidgets/pdfviewer/mainwindow.cpp | 2 ++ examples/pdfwidgets/pdfviewer/mainwindow.ui | 44 +++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 7 deletions(-) (limited to 'examples') diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp index d865a8bdd..8ef7a075e 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp +++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp @@ -87,6 +87,8 @@ void MainWindow::open(const QUrl &docLocation) { if (docLocation.isLocalFile()) { m_document->load(docLocation.toLocalFile()); + const auto documentTitle = m_document->metaData(QPdfDocument::Title).toString(); + setWindowTitle(!documentTitle.isEmpty() ? documentTitle : QStringLiteral("PDF Viewer")); } 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())); diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.ui b/examples/pdfwidgets/pdfviewer/mainwindow.ui index 7070619b9..251591d9a 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.ui +++ b/examples/pdfwidgets/pdfviewer/mainwindow.ui @@ -6,17 +6,41 @@ 0 0 - 400 - 300 + 700 + 600 - MainWindow + PDF Viewer + + + true + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + QFrame::NoFrame + + + 0 + true @@ -25,8 +49,8 @@ 0 0 - 380 - 200 + 700 + 517 @@ -40,8 +64,8 @@ 0 0 - 400 - 19 + 700 + 22 @@ -72,6 +96,12 @@ + + false + + + false + TopToolBarArea -- cgit v1.2.3 From 2cf4bb16c66050496cbdd2dcd3aa62c0a339a1f3 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 21 Feb 2017 12:50:56 +0100 Subject: Add bookmarks view to pdfviewer example Add a treeview to the pdfviewer example to show the usage of QPdfBookmarkModel Change-Id: Ia93d868655a74ea6c41bb28945fe16d0cc740410 Reviewed-by: Simon Hausmann --- examples/pdfwidgets/pdfviewer/mainwindow.cpp | 18 ++++ examples/pdfwidgets/pdfviewer/mainwindow.h | 1 + examples/pdfwidgets/pdfviewer/mainwindow.ui | 122 ++++++++++++++++++++++----- 3 files changed, 121 insertions(+), 20 deletions(-) (limited to 'examples') diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp index 8ef7a075e..fd2656305 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp +++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,14 @@ MainWindow::MainWindow(QWidget *parent) QScroller::grabGesture(ui->scrollArea); + QPdfBookmarkModel *bookmarkModel = new QPdfBookmarkModel(this); + bookmarkModel->setDocument(m_document); + + ui->bookmarkView->setModel(bookmarkModel); + connect(ui->bookmarkView, SIGNAL(activated(QModelIndex)), this, SLOT(bookmarkSelected(QModelIndex))); + + ui->tabWidget->setTabEnabled(1, false); // disable 'Pages' tab for now + m_pageWidget->setDocument(m_document); } @@ -120,6 +129,15 @@ void MainWindow::zoomEdited() m_pageWidget->setZoom(factor / 100.); } +void MainWindow::bookmarkSelected(const QModelIndex &index) +{ + if (!index.isValid()) + return; + + const int page = index.data(QPdfBookmarkModel::PageNumberRole).toInt(); + ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(page)); +} + void MainWindow::on_actionOpen_triggered() { QUrl toOpen = QFileDialog::getOpenFileUrl(this, tr("Choose a PDF"), QUrl(), "Portable Documents (*.pdf)"); diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h index dedc81267..40062a31d 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.h +++ b/examples/pdfwidgets/pdfviewer/mainwindow.h @@ -65,6 +65,7 @@ private slots: void showingPageRange(int start, int end); void zoomChanged(qreal factor); void zoomEdited(); + void bookmarkSelected(const QModelIndex &index); // action handlers void on_actionOpen_triggered(); diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.ui b/examples/pdfwidgets/pdfviewer/mainwindow.ui index 251591d9a..738cef48d 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.ui +++ b/examples/pdfwidgets/pdfviewer/mainwindow.ui @@ -34,27 +34,109 @@ 0 - - - QFrame::NoFrame - - - 0 - - - true - - - - - 0 - 0 - 700 - 517 - + + + + 0 - - + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + QTabWidget::West + + + 0 + + + false + + + + Bookmarks + + + + 0 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + 0 + 0 + + + + true + + + + + + + + Pages + + + + + + + 10 + 0 + + + + true + + + + + 0 + 0 + 401 + 515 + + + + + + + -- cgit v1.2.3 From 9bfe4bf9802281fabc5b9e607621ea4cb5e9bd39 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 22 Aug 2016 20:09:38 +0200 Subject: Add support for render rotation and flags Extend the QPdfDocument::render() method with a parameter of new type QPdfDocumentRenderOptions to specify the rotation and additional render flags. Change-Id: I354acc7fad4d094a96cefcea4dfa3513f4955c47 Reviewed-by: Marc Mutz --- examples/pdfwidgets/pdfviewer/pagerenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/pdfwidgets/pdfviewer/pagerenderer.cpp b/examples/pdfwidgets/pdfviewer/pagerenderer.cpp index c8f245640..8cb1ed69c 100644 --- a/examples/pdfwidgets/pdfviewer/pagerenderer.cpp +++ b/examples/pdfwidgets/pdfviewer/pagerenderer.cpp @@ -84,7 +84,7 @@ void PageRenderer::renderPage(int page, qreal zoom) QElapsedTimer timer; timer.start(); - const QImage &img = m_document->render(page, size); + const QImage &img = m_document->render(page, size.toSize()); const qreal secs = timer.nsecsElapsed() / 1000000000.0; if (secs < m_minRenderTime) -- cgit v1.2.3 From bc6c48dde1a697ce2472f954b3a1cb9928715b5f Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 3 Feb 2018 12:16:43 +0100 Subject: Fix compilation with custom Qt namespace Fix the compilation of QtPdf examples when compiled against a Qt version that uses a custom namespace. Change-Id: I3bd8d89a3ad1e270ed1d54c2b0a458e967f21cca Reviewed-by: Frederik Gladhorn --- examples/pdfwidgets/pdfviewer/mainwindow.h | 3 +++ examples/pdfwidgets/pdfviewer/pagerenderer.h | 2 ++ examples/pdfwidgets/pdfviewer/sequentialpagewidget.h | 3 +++ 3 files changed, 8 insertions(+) (limited to 'examples') diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h index 40062a31d..f29205840 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.h +++ b/examples/pdfwidgets/pdfviewer/mainwindow.h @@ -42,12 +42,15 @@ Q_DECLARE_LOGGING_CATEGORY(lcExample) +QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } class QLineEdit; class QPdfDocument; +QT_END_NAMESPACE + class SequentialPageWidget; class MainWindow : public QMainWindow diff --git a/examples/pdfwidgets/pdfviewer/pagerenderer.h b/examples/pdfwidgets/pdfviewer/pagerenderer.h index 5feccaac6..f1e491889 100644 --- a/examples/pdfwidgets/pdfviewer/pagerenderer.h +++ b/examples/pdfwidgets/pdfviewer/pagerenderer.h @@ -40,7 +40,9 @@ #include #include +QT_BEGIN_NAMESPACE class QPdfDocument; +QT_END_NAMESPACE class PageRenderer : public QThread { diff --git a/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h b/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h index 85f35713c..a84a37bb0 100644 --- a/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h +++ b/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h @@ -39,7 +39,10 @@ #include +QT_BEGIN_NAMESPACE class QPdfDocument; +QT_END_NAMESPACE + class PageRenderer; class SequentialPageWidget : public QWidget -- cgit v1.2.3 From b2b219dcd218260c6a304f1cdf016f4dde250dd2 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Fri, 24 Feb 2017 10:59:12 +0100 Subject: Port pdfviewer example to QPdfView widget Change-Id: Id651a2c179628506f0955751abda57cbae569ee9 Reviewed-by: Simon Hausmann --- examples/pdfwidgets/pdfviewer/mainwindow.cpp | 88 ++++------ examples/pdfwidgets/pdfviewer/mainwindow.h | 15 +- examples/pdfwidgets/pdfviewer/mainwindow.ui | 42 ++--- examples/pdfwidgets/pdfviewer/pagerenderer.cpp | 105 ----------- examples/pdfwidgets/pdfviewer/pagerenderer.h | 82 --------- examples/pdfwidgets/pdfviewer/pageselector.cpp | 111 ++++++++++++ examples/pdfwidgets/pdfviewer/pageselector.h | 72 ++++++++ examples/pdfwidgets/pdfviewer/pdfviewer.pro | 24 +-- .../pdfwidgets/pdfviewer/sequentialpagewidget.cpp | 192 --------------------- .../pdfwidgets/pdfviewer/sequentialpagewidget.h | 99 ----------- examples/pdfwidgets/pdfviewer/zoomselector.cpp | 97 +++++++++++ examples/pdfwidgets/pdfviewer/zoomselector.h | 63 +++++++ 12 files changed, 411 insertions(+), 579 deletions(-) delete mode 100644 examples/pdfwidgets/pdfviewer/pagerenderer.cpp delete mode 100644 examples/pdfwidgets/pdfviewer/pagerenderer.h create mode 100644 examples/pdfwidgets/pdfviewer/pageselector.cpp create mode 100644 examples/pdfwidgets/pdfviewer/pageselector.h delete mode 100644 examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp delete mode 100644 examples/pdfwidgets/pdfviewer/sequentialpagewidget.h create mode 100644 examples/pdfwidgets/pdfviewer/zoomselector.cpp create mode 100644 examples/pdfwidgets/pdfviewer/zoomselector.h (limited to 'examples') diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp index fd2656305..5f9bf389f 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp +++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp @@ -37,14 +37,14 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -#include "sequentialpagewidget.h" +#include "pageselector.h" +#include "zoomselector.h" #include -#include #include #include #include -#include +#include #include const qreal zoomMultiplier = qSqrt(2.0); @@ -54,27 +54,23 @@ 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_zoomSelector(new ZoomSelector(this)) + , m_pageSelector(new PageSelector(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_zoomSelector->setMaximumWidth(150); + ui->mainToolBar->insertWidget(ui->actionZoom_In, m_zoomSelector); + + m_pageSelector->setMaximumWidth(150); + ui->mainToolBar->addWidget(m_pageSelector); + + m_pageSelector->setPageNavigation(ui->pdfView->pageNavigation()); + + connect(m_zoomSelector, &ZoomSelector::zoomModeChanged, ui->pdfView, &QPdfView::setZoomMode); + connect(m_zoomSelector, &ZoomSelector::zoomFactorChanged, ui->pdfView, &QPdfView::setZoomFactor); + m_zoomSelector->reset(); QPdfBookmarkModel *bookmarkModel = new QPdfBookmarkModel(this); bookmarkModel->setDocument(m_document); @@ -84,7 +80,10 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setTabEnabled(1, false); // disable 'Pages' tab for now - m_pageWidget->setDocument(m_document); + ui->pdfView->setDocument(m_document); + + connect(ui->pdfView, &QPdfView::zoomFactorChanged, + m_zoomSelector, &ZoomSelector::setZoomFactor); } MainWindow::~MainWindow() @@ -103,30 +102,6 @@ void MainWindow::open(const QUrl &docLocation) 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::bookmarkSelected(const QModelIndex &index) @@ -135,7 +110,7 @@ void MainWindow::bookmarkSelected(const QModelIndex &index) return; const int page = index.data(QPdfBookmarkModel::PageNumberRole).toInt(); - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(page)); + ui->pdfView->pageNavigation()->setCurrentPage(page); } void MainWindow::on_actionOpen_triggered() @@ -163,28 +138,25 @@ void MainWindow::on_actionAbout_Qt_triggered() void MainWindow::on_actionZoom_In_triggered() { - m_pageWidget->setZoom(m_pageWidget->zoom() * zoomMultiplier); + ui->pdfView->setZoomFactor(ui->pdfView->zoomFactor() * zoomMultiplier); } void MainWindow::on_actionZoom_Out_triggered() { - m_pageWidget->setZoom(m_pageWidget->zoom() / zoomMultiplier); + ui->pdfView->setZoomFactor(ui->pdfView->zoomFactor() / zoomMultiplier); } -void MainWindow::on_actionGo_triggered() +void MainWindow::on_actionPrevious_Page_triggered() { - bool ok = false; - int page = m_pageEdit->text().toInt(&ok); - if (!ok) return; - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(page)); + ui->pdfView->pageNavigation()->goToPreviousPage(); } -void MainWindow::on_actionPrevious_Page_triggered() +void MainWindow::on_actionNext_Page_triggered() { - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(m_pageWidget->topPageShowing() - 1)); + ui->pdfView->pageNavigation()->goToNextPage(); } -void MainWindow::on_actionNext_Page_triggered() +void MainWindow::on_actionContinuous_triggered() { - ui->scrollArea->ensureVisible(0, m_pageWidget->yForPage(m_pageWidget->bottomPageShowing() + 1)); + ui->pdfView->setPageMode(ui->actionContinuous->isChecked() ? QPdfView::MultiPage : QPdfView::SinglePage); } diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h index f29205840..afdfcade4 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.h +++ b/examples/pdfwidgets/pdfviewer/mainwindow.h @@ -47,11 +47,12 @@ namespace Ui { class MainWindow; } -class QLineEdit; class QPdfDocument; +class QPdfView; QT_END_NAMESPACE -class SequentialPageWidget; +class PageSelector; +class ZoomSelector; class MainWindow : public QMainWindow { @@ -65,9 +66,6 @@ public slots: void open(const QUrl &docLocation); private slots: - void showingPageRange(int start, int end); - void zoomChanged(qreal factor); - void zoomEdited(); void bookmarkSelected(const QModelIndex &index); // action handlers @@ -77,15 +75,14 @@ private slots: 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(); + void on_actionContinuous_triggered(); private: Ui::MainWindow *ui; - SequentialPageWidget *m_pageWidget; - QLineEdit *m_zoomEdit; - QLineEdit *m_pageEdit; + ZoomSelector *m_zoomSelector; + PageSelector *m_pageSelector; QPdfDocument *m_document; }; diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.ui b/examples/pdfwidgets/pdfviewer/mainwindow.ui index 738cef48d..2651525a5 100644 --- a/examples/pdfwidgets/pdfviewer/mainwindow.ui +++ b/examples/pdfwidgets/pdfviewer/mainwindow.ui @@ -113,26 +113,13 @@ - + 10 0 - - true - - - - - 0 - 0 - 401 - 515 - - - @@ -172,6 +159,8 @@ + + @@ -195,7 +184,6 @@ - @@ -252,14 +240,6 @@ Ctrl+- - - - Go - - - Go to Page - - Previous Page @@ -276,8 +256,24 @@ PgDown + + + true + + + Continuous + + + + + QPdfView + QWidget +
qpdfview.h
+ 1 +
+
diff --git a/examples/pdfwidgets/pdfviewer/pagerenderer.cpp b/examples/pdfwidgets/pdfviewer/pagerenderer.cpp deleted file mode 100644 index 8cb1ed69c..000000000 --- a/examples/pdfwidgets/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.toSize()); - - 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 deleted file mode 100644 index f1e491889..000000000 --- a/examples/pdfwidgets/pdfviewer/pagerenderer.h +++ /dev/null @@ -1,82 +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 - -QT_BEGIN_NAMESPACE -class QPdfDocument; -QT_END_NAMESPACE - -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/pageselector.cpp b/examples/pdfwidgets/pdfviewer/pageselector.cpp new file mode 100644 index 000000000..cd3c4ba0e --- /dev/null +++ b/examples/pdfwidgets/pdfviewer/pageselector.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** 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 "pageselector.h" + +#include +#include +#include +#include +#include + +PageSelector::PageSelector(QWidget *parent) + : QWidget(parent) + , m_pageNavigation(nullptr) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + + m_previousPageButton = new QToolButton(this); + m_previousPageButton->setText("<"); + m_previousPageButton->setEnabled(false); + + m_pageNumberEdit = new QLineEdit(this); + m_pageNumberEdit->setAlignment(Qt::AlignRight); + + m_pageCountLabel = new QLabel(this); + m_pageCountLabel->setText("0"); + + m_nextPageButton = new QToolButton(this); + m_nextPageButton->setText(">"); + m_nextPageButton->setEnabled(false); + + layout->addWidget(m_previousPageButton); + layout->addWidget(m_pageNumberEdit); + layout->addWidget(m_pageCountLabel); + layout->addWidget(m_nextPageButton); +} + +void PageSelector::setPageNavigation(QPdfPageNavigation *pageNavigation) +{ + m_pageNavigation = pageNavigation; + + connect(m_previousPageButton, &QToolButton::clicked, m_pageNavigation, &QPdfPageNavigation::goToPreviousPage); + connect(m_pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged, m_previousPageButton, &QToolButton::setEnabled); + + connect(m_pageNavigation, &QPdfPageNavigation::currentPageChanged, this, &PageSelector::onCurrentPageChanged); + connect(m_pageNavigation, &QPdfPageNavigation::pageCountChanged, this, [this](int pageCount){ m_pageCountLabel->setText(QString::fromLatin1("/ %1").arg(pageCount)); }); + + connect(m_pageNumberEdit, &QLineEdit::editingFinished, this, &PageSelector::pageNumberEdited); + + connect(m_nextPageButton, &QToolButton::clicked, m_pageNavigation, &QPdfPageNavigation::goToNextPage); + connect(m_pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged, m_nextPageButton, &QToolButton::setEnabled); + + onCurrentPageChanged(m_pageNavigation->currentPage()); +} + +void PageSelector::onCurrentPageChanged(int page) +{ + if (m_pageNavigation->pageCount() == 0) + m_pageNumberEdit->setText(QString::number(0)); + else + m_pageNumberEdit->setText(QString::number(page + 1)); +} + +void PageSelector::pageNumberEdited() +{ + if (!m_pageNavigation) + return; + + const QString text = m_pageNumberEdit->text(); + + bool ok = false; + const int pageNumber = text.toInt(&ok); + + if (!ok) + onCurrentPageChanged(m_pageNavigation->currentPage()); + else + m_pageNavigation->setCurrentPage(qBound(0, pageNumber - 1, m_pageNavigation->pageCount() - 1)); +} diff --git a/examples/pdfwidgets/pdfviewer/pageselector.h b/examples/pdfwidgets/pdfviewer/pageselector.h new file mode 100644 index 000000000..7a7283f99 --- /dev/null +++ b/examples/pdfwidgets/pdfviewer/pageselector.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** 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 PAGESELECTOR_H +#define PAGESELECTOR_H + +#include + +QT_BEGIN_NAMESPACE +class QLabel; +class QLineEdit; +class QPdfDocument; +class QPdfPageNavigation; +class QToolButton; +QT_END_NAMESPACE + +class PageSelector : public QWidget +{ + Q_OBJECT + +public: + explicit PageSelector(QWidget *parent = nullptr); + + void setPageNavigation(QPdfPageNavigation *pageNavigation); + +private slots: + void onCurrentPageChanged(int page); + void pageNumberEdited(); + +private: + QPdfPageNavigation *m_pageNavigation; + + QLineEdit *m_pageNumberEdit; + QLabel *m_pageCountLabel; + QToolButton *m_previousPageButton; + QToolButton *m_nextPageButton; +}; + +#endif // PAGESELECTOR_H diff --git a/examples/pdfwidgets/pdfviewer/pdfviewer.pro b/examples/pdfwidgets/pdfviewer/pdfviewer.pro index 10cacce6e..d3e768892 100644 --- a/examples/pdfwidgets/pdfviewer/pdfviewer.pro +++ b/examples/pdfwidgets/pdfviewer/pdfviewer.pro @@ -1,21 +1,23 @@ -QT += core gui widgets pdf -TARGET = pdfviewer TEMPLATE = app +TARGET = pdfviewer +QT += core gui widgets pdfwidgets -SOURCES += main.cpp\ - mainwindow.cpp \ - sequentialpagewidget.cpp \ - pagerenderer.cpp +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + pageselector.cpp \ + zoomselector.cpp -HEADERS += mainwindow.h \ - sequentialpagewidget.h \ - pagerenderer.h +HEADERS += \ + mainwindow.h \ + pageselector.h \ + zoomselector.h -FORMS += mainwindow.ui +FORMS += \ + mainwindow.ui RESOURCES += \ resources.qrc target.path = $$[QT_INSTALL_EXAMPLES]/pdf/pdfviewer INSTALLS += target - diff --git a/examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp b/examples/pdfwidgets/pdfviewer/sequentialpagewidget.cpp deleted file mode 100644 index 904bc17d2..000000000 --- a/examples/pdfwidgets/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/pdfwidgets/pdfviewer/sequentialpagewidget.h b/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h deleted file mode 100644 index a84a37bb0..000000000 --- a/examples/pdfwidgets/pdfviewer/sequentialpagewidget.h +++ /dev/null @@ -1,99 +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 - -QT_BEGIN_NAMESPACE -class QPdfDocument; -QT_END_NAMESPACE - -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/pdfwidgets/pdfviewer/zoomselector.cpp b/examples/pdfwidgets/pdfviewer/zoomselector.cpp new file mode 100644 index 000000000..0205489aa --- /dev/null +++ b/examples/pdfwidgets/pdfviewer/zoomselector.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** 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 "zoomselector.h" + +#include + +ZoomSelector::ZoomSelector(QWidget *parent) + : QComboBox(parent) +{ + setEditable(true); + + addItem(QLatin1String("Fit Width")); + addItem(QLatin1String("Fit Page")); + addItem(QLatin1String("12%")); + addItem(QLatin1String("25%")); + addItem(QLatin1String("33%")); + addItem(QLatin1String("50%")); + addItem(QLatin1String("66%")); + addItem(QLatin1String("75%")); + addItem(QLatin1String("100%")); + addItem(QLatin1String("125%")); + addItem(QLatin1String("150%")); + addItem(QLatin1String("200%")); + addItem(QLatin1String("400%")); + + connect(this, static_cast(&QComboBox::currentIndexChanged), + this, &ZoomSelector::onCurrentTextChanged); + + connect(lineEdit(), &QLineEdit::editingFinished, + this, [this](){onCurrentTextChanged(lineEdit()->text()); }); +} + +void ZoomSelector::setZoomFactor(qreal zoomFactor) +{ + setCurrentText(QString::number(qRound(zoomFactor * 100)) + QLatin1String("%")); +} + +void ZoomSelector::reset() +{ + setCurrentIndex(8); // 100% +} + +void ZoomSelector::onCurrentTextChanged(const QString &text) +{ + if (text == QLatin1String("Fit Width")) { + emit zoomModeChanged(QPdfView::FitToWidth); + } else if (text == QLatin1String("Fit Page")) { + emit zoomModeChanged(QPdfView::FitInView); + } else { + qreal factor = 1.0; + + QString withoutPercent(text); + withoutPercent.remove(QLatin1Char('%')); + + bool ok = false; + const int zoomLevel = withoutPercent.toInt(&ok); + if (ok) + factor = zoomLevel / 100.0; + + emit zoomModeChanged(QPdfView::CustomZoom); + emit zoomFactorChanged(factor); + } +} diff --git a/examples/pdfwidgets/pdfviewer/zoomselector.h b/examples/pdfwidgets/pdfviewer/zoomselector.h new file mode 100644 index 000000000..c58d09970 --- /dev/null +++ b/examples/pdfwidgets/pdfviewer/zoomselector.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** 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 ZOOMSELECTOR_H +#define ZOOMSELECTOR_H + +#include +#include + +class ZoomSelector : public QComboBox +{ + Q_OBJECT + +public: + explicit ZoomSelector(QWidget *parent = nullptr); + +public slots: + void setZoomFactor(qreal zoomFactor); + + void reset(); + +signals: + void zoomModeChanged(QPdfView::ZoomMode zoomMode); + void zoomFactorChanged(qreal zoomFactor); + +private slots: + void onCurrentTextChanged(const QString &text); +}; + +#endif // ZOOMSELECTOR_H -- cgit v1.2.3 From 883f2a9969f02941f018b828749fea97d8b56582 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 18 Jul 2018 11:06:14 +0200 Subject: Add QtPdf and QtPdfWidgets modules This change adds two new modules to qtwebengine repository. New modules do not depend on webengine module, however webengine chromium source code and Chromium "gn" configuration is required to build QtPdf. Adding two unrelated modules to webengine might look crazy: however sharing gn build configuration and Chromium code base with necessary qt adaptations simplifies code maintenance and minimises required code checkouts. Back porting of security patches for Chromium also affects Pdfium. Moreover, Pdfium is no longer a separate project, but integrated into Chromium: therefore moving it out of Chromium source tree would require extra effort. Rename webengine-core feature to build-qtwebengine-core, this makes consistent feature naming with build-qtpdf At the moment two new modules have integrated build, with possible shortcuts: qmake -- --no-build-qtwebengine-core qmake -- --no-build-qtpdf Webengine build is disabled by default now. Change-Id: Iac3d9927d51f3ac316db0148d275eda843dcc19b Reviewed-by: Shawn Rutledge --- examples/examples.pro | 2 ++ examples/pdfwidgets/pdfviewer/pdfviewer.pro | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/examples.pro b/examples/examples.pro index 3dac9b0b7..825cacaae 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -3,3 +3,5 @@ TEMPLATE=subdirs qtHaveModule(webengine): SUBDIRS += webengine qtHaveModule(webenginewidgets): SUBDIRS += webenginewidgets + +qtHaveModule(pdfwidgets): SUBDIRS += pdfwidgets diff --git a/examples/pdfwidgets/pdfviewer/pdfviewer.pro b/examples/pdfwidgets/pdfviewer/pdfviewer.pro index d3e768892..ad0607ea5 100644 --- a/examples/pdfwidgets/pdfviewer/pdfviewer.pro +++ b/examples/pdfwidgets/pdfviewer/pdfviewer.pro @@ -19,5 +19,5 @@ FORMS += \ RESOURCES += \ resources.qrc -target.path = $$[QT_INSTALL_EXAMPLES]/pdf/pdfviewer +target.path = $$[QT_INSTALL_EXAMPLES]/pdfwidgets/pdfviewer INSTALLS += target -- cgit v1.2.3 From b6dd845ec4a6bfb6b620686681e20d38a2f24101 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 26 Aug 2019 15:31:00 +0200 Subject: Add QPdfSearchModel, QML PdfSearchModel and PdfPageView This enables searching a PDF for a text string and getting the boundaries of the areas where it is found. The boundaries are returned as polygons intended to be rendered with PathMultiline. PdfPageView is a QML component intended to be a drop-in viewer for use in applications that need the most common PDF viewing functionality. More advanced applications are free to use it as a starting point for customization. Task-number: QTBUG-77507 Task-number: QTBUG-77514 Change-Id: Id08ac30224e41b6cdfb9300cc4288d5750259f78 Reviewed-by: Shawn Rutledge --- examples/examples.pro | 2 + examples/pdf/pdf.pro | 3 + examples/pdf/pdfviewer/main.cpp | 70 ++++++++ examples/pdf/pdfviewer/pdfviewer.pro | 14 ++ examples/pdf/pdfviewer/resources/document-open.svg | 13 ++ examples/pdf/pdfviewer/resources/edit-clear.svg | 15 ++ .../pdf/pdfviewer/resources/go-next-view-page.svg | 13 ++ .../pdfviewer/resources/go-previous-view-page.svg | 13 ++ examples/pdf/pdfviewer/resources/zoom-in.svg | 13 ++ examples/pdf/pdfviewer/resources/zoom-original.svg | 13 ++ examples/pdf/pdfviewer/resources/zoom-out.svg | 13 ++ examples/pdf/pdfviewer/viewer.qml | 188 +++++++++++++++++++++ examples/pdf/pdfviewer/viewer.qrc | 12 ++ 13 files changed, 382 insertions(+) create mode 100644 examples/pdf/pdf.pro create mode 100644 examples/pdf/pdfviewer/main.cpp create mode 100644 examples/pdf/pdfviewer/pdfviewer.pro create mode 100644 examples/pdf/pdfviewer/resources/document-open.svg create mode 100644 examples/pdf/pdfviewer/resources/edit-clear.svg create mode 100644 examples/pdf/pdfviewer/resources/go-next-view-page.svg create mode 100644 examples/pdf/pdfviewer/resources/go-previous-view-page.svg create mode 100644 examples/pdf/pdfviewer/resources/zoom-in.svg create mode 100644 examples/pdf/pdfviewer/resources/zoom-original.svg create mode 100644 examples/pdf/pdfviewer/resources/zoom-out.svg create mode 100644 examples/pdf/pdfviewer/viewer.qml create mode 100644 examples/pdf/pdfviewer/viewer.qrc (limited to 'examples') diff --git a/examples/examples.pro b/examples/examples.pro index 825cacaae..b4f411aeb 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -5,3 +5,5 @@ qtHaveModule(webengine): SUBDIRS += webengine qtHaveModule(webenginewidgets): SUBDIRS += webenginewidgets qtHaveModule(pdfwidgets): SUBDIRS += pdfwidgets + +qtHaveModule(quick): qtHaveModule(pdf): qtHaveModule(pdfwidgets): SUBDIRS += pdf diff --git a/examples/pdf/pdf.pro b/examples/pdf/pdf.pro new file mode 100644 index 000000000..45df33e46 --- /dev/null +++ b/examples/pdf/pdf.pro @@ -0,0 +1,3 @@ +TEMPLATE=subdirs + +SUBDIRS += pdfviewer diff --git a/examples/pdf/pdfviewer/main.cpp b/examples/pdf/pdfviewer/main.cpp new file mode 100644 index 000000000..6b94a3de1 --- /dev/null +++ b/examples/pdf/pdfviewer/main.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + QCoreApplication::setApplicationName("Qt Quick PDF Viewer Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:///pdfviewer/viewer.qml"))); + if (app.arguments().count() > 1) { + QUrl toLoad = QUrl::fromUserInput(app.arguments().at(1)); + engine.rootObjects().first()->setProperty("source", toLoad); + } + + return app.exec(); +} diff --git a/examples/pdf/pdfviewer/pdfviewer.pro b/examples/pdf/pdfviewer/pdfviewer.pro new file mode 100644 index 000000000..697349cee --- /dev/null +++ b/examples/pdf/pdfviewer/pdfviewer.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += qml quick pdf widgets + +SOURCES += main.cpp + +RESOURCES += \ + viewer.qrc +EXAMPLE_FILES = \ + viewer.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/pdf/pdfviewer +INSTALLS += target + diff --git a/examples/pdf/pdfviewer/resources/document-open.svg b/examples/pdf/pdfviewer/resources/document-open.svg new file mode 100644 index 000000000..bf23123a3 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/document-open.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/edit-clear.svg b/examples/pdf/pdfviewer/resources/edit-clear.svg new file mode 100644 index 000000000..1c35aaf04 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/edit-clear.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/go-next-view-page.svg b/examples/pdf/pdfviewer/resources/go-next-view-page.svg new file mode 100644 index 000000000..e453ddbec --- /dev/null +++ b/examples/pdf/pdfviewer/resources/go-next-view-page.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/go-previous-view-page.svg b/examples/pdf/pdfviewer/resources/go-previous-view-page.svg new file mode 100644 index 000000000..b032309e9 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/go-previous-view-page.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/zoom-in.svg b/examples/pdf/pdfviewer/resources/zoom-in.svg new file mode 100644 index 000000000..efdc9f17d --- /dev/null +++ b/examples/pdf/pdfviewer/resources/zoom-in.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/zoom-original.svg b/examples/pdf/pdfviewer/resources/zoom-original.svg new file mode 100644 index 000000000..1b4080a03 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/zoom-original.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/zoom-out.svg b/examples/pdf/pdfviewer/resources/zoom-out.svg new file mode 100644 index 000000000..fcde9e526 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/zoom-out.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/viewer.qml b/examples/pdf/pdfviewer/viewer.qml new file mode 100644 index 000000000..47853aa31 --- /dev/null +++ b/examples/pdf/pdfviewer/viewer.qml @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Pdf 5.15 +import QtQuick.Shapes 1.15 +import QtQuick.Window 2.15 +import Qt.labs.platform 1.1 as Platform + +ApplicationWindow { + id: root + width: 800 + height: 640 + color: "lightgrey" + title: document.title + visible: true + property alias source: document.source // for main.cpp + property real scaleStep: Math.sqrt(2) + + header: ToolBar { + RowLayout { + anchors.fill: parent + anchors.rightMargin: 6 + ToolButton { + action: Action { + shortcut: StandardKey.Open + icon.source: "resources/document-open.svg" + onTriggered: fileDialog.open() + } + } + ToolButton { + action: Action { + shortcut: StandardKey.ZoomIn + enabled: pageView.sourceSize.width < 10000 + icon.source: "resources/zoom-in.svg" + onTriggered: pageView.renderScale *= root.scaleStep + } + } + ToolButton { + action: Action { + shortcut: StandardKey.ZoomOut + enabled: pageView.sourceSize.width > 50 + icon.source: "resources/zoom-out.svg" + onTriggered: pageView.renderScale /= root.scaleStep + } + } + ToolButton { + action: Action { + shortcut: "Ctrl+0" + icon.source: "resources/zoom-original.svg" + onTriggered: pageView.renderScale = 1 + } + } + ToolButton { + action: Action { + shortcut: StandardKey.MoveToPreviousPage + icon.source: "resources/go-previous-view-page.svg" + enabled: pageView.currentPage > 0 + onTriggered: pageView.currentPage-- + } + } + ToolButton { + action: Action { + shortcut: StandardKey.MoveToNextPage + icon.source: "resources/go-next-view-page.svg" + enabled: pageView.currentPage < pageView.pageCount - 1 + onTriggered: pageView.currentPage++ + } + } + TextField { + id: searchField + placeholderText: "search" + Layout.minimumWidth: 200 + Layout.fillWidth: true + Image { + visible: searchField.text !== "" + source: "resources/edit-clear.svg" + anchors { + right: parent.right + top: parent.top + bottom: parent.bottom + margins: 3 + rightMargin: 5 + } + TapHandler { + onTapped: searchField.clear() + } + } + } + Shortcut { + sequence: StandardKey.Find + onActivated: searchField.forceActiveFocus() + } + Shortcut { + sequence: StandardKey.Quit + onActivated: Qt.quit() + } + } + } + + Platform.FileDialog { + id: fileDialog + title: "Open a PDF file" + nameFilters: [ "PDF files (*.pdf)" ] + onAccepted: document.source = file + } + + Dialog { + id: errorDialog + title: "Error loading " + document.source + standardButtons: Dialog.Ok + modal: true + closePolicy: Popup.CloseOnEscape + anchors.centerIn: parent + width: 300 + + Label { + id: errorField + text: document.error + } + } + + PdfPageView { + id: pageView + document: PdfDocument { + id: document + onStatusChanged: if (status === PdfDocument.Error) errorDialog.open() + } + searchString: searchField.text + } + + footer: Label { + property size implicitPointSize: document.pagePointSize(pageView.currentPage) + text: "page " + (pageView.currentPage + 1) + " of " + pageView.pageCount + + " scale " + pageView.renderScale.toFixed(2) + + " sourceSize " + pageView.sourceSize.width.toFixed(1) + "x" + pageView.sourceSize.height.toFixed(1) + + " original " + implicitPointSize.width.toFixed(1) + "x" + implicitPointSize.height.toFixed(1) + visible: pageView.pageCount > 0 + } +} diff --git a/examples/pdf/pdfviewer/viewer.qrc b/examples/pdf/pdfviewer/viewer.qrc new file mode 100644 index 000000000..59045b75c --- /dev/null +++ b/examples/pdf/pdfviewer/viewer.qrc @@ -0,0 +1,12 @@ + + + viewer.qml + resources/edit-clear.svg + resources/go-next-view-page.svg + resources/go-previous-view-page.svg + resources/zoom-in.svg + resources/zoom-original.svg + resources/zoom-out.svg + resources/document-open.svg + + -- cgit v1.2.3 From 3db65542c26ef4926ed4716efb9f7a0f847ca907 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 16 Oct 2019 19:47:51 +0200 Subject: Add rotation actions to the QML pdf viewer example Task-number: QTBUG-77514 Change-Id: Ifa7515dae18b278e038c2e5fad46492ca158b044 Reviewed-by: Michal Klocek --- examples/pdf/pdfviewer/resources/rotate-left.svg | 6 ++++++ examples/pdf/pdfviewer/resources/rotate-right.svg | 6 ++++++ examples/pdf/pdfviewer/viewer.qml | 14 ++++++++++++++ examples/pdf/pdfviewer/viewer.qrc | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 examples/pdf/pdfviewer/resources/rotate-left.svg create mode 100644 examples/pdf/pdfviewer/resources/rotate-right.svg (limited to 'examples') diff --git a/examples/pdf/pdfviewer/resources/rotate-left.svg b/examples/pdf/pdfviewer/resources/rotate-left.svg new file mode 100644 index 000000000..90ce53c9d --- /dev/null +++ b/examples/pdf/pdfviewer/resources/rotate-left.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/resources/rotate-right.svg b/examples/pdf/pdfviewer/resources/rotate-right.svg new file mode 100644 index 000000000..7383d1c84 --- /dev/null +++ b/examples/pdf/pdfviewer/resources/rotate-right.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/examples/pdf/pdfviewer/viewer.qml b/examples/pdf/pdfviewer/viewer.qml index 47853aa31..adc2a4b5b 100644 --- a/examples/pdf/pdfviewer/viewer.qml +++ b/examples/pdf/pdfviewer/viewer.qml @@ -99,6 +99,20 @@ ApplicationWindow { onTriggered: pageView.renderScale = 1 } } + ToolButton { + action: Action { + shortcut: "Ctrl+L" + icon.source: "resources/rotate-left.svg" + onTriggered: pageView.rotation -= 90 + } + } + ToolButton { + action: Action { + shortcut: "Ctrl+R" + icon.source: "resources/rotate-right.svg" + onTriggered: pageView.rotation += 90 + } + } ToolButton { action: Action { shortcut: StandardKey.MoveToPreviousPage diff --git a/examples/pdf/pdfviewer/viewer.qrc b/examples/pdf/pdfviewer/viewer.qrc index 59045b75c..78f9c8d30 100644 --- a/examples/pdf/pdfviewer/viewer.qrc +++ b/examples/pdf/pdfviewer/viewer.qrc @@ -4,6 +4,8 @@ resources/edit-clear.svg resources/go-next-view-page.svg resources/go-previous-view-page.svg + resources/rotate-left.svg + resources/rotate-right.svg resources/zoom-in.svg resources/zoom-original.svg resources/zoom-out.svg -- cgit v1.2.3