summaryrefslogtreecommitdiffstats
path: root/examples/widgets/pdfviewer/sequentialpagewidget.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@theqtcompany.com>2014-12-15 22:30:01 +0100
committerShawn Rutledge <shawn.rutledge@theqtcompany.com>2014-12-16 00:45:47 +0100
commit86b7ed4df30f57fb994e5d032070ed118a9a7afa (patch)
tree1a0b7277772826be337ab4f025b1e23214f798f2 /examples/widgets/pdfviewer/sequentialpagewidget.cpp
parent5359a1473bf5c2310c50dbe239c28084cf7ae81f (diff)
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.
Diffstat (limited to 'examples/widgets/pdfviewer/sequentialpagewidget.cpp')
-rw-r--r--examples/widgets/pdfviewer/sequentialpagewidget.cpp74
1 files changed, 41 insertions, 33 deletions
diff --git a/examples/widgets/pdfviewer/sequentialpagewidget.cpp b/examples/widgets/pdfviewer/sequentialpagewidget.cpp
index da880be..2f4e3fb 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 <QPaintEvent>
#include <QPainter>
#include <QPdfDocument>
@@ -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;