diff options
author | joe berner <stackyjoe@gmail.com> | 2018-12-18 10:59:15 -0600 |
---|---|---|
committer | joe berner <stackyjoe@gmail.com> | 2018-12-18 10:59:15 -0600 |
commit | e42bc7e16e6d9f813b5c712261dffbef6b1bddb2 (patch) | |
tree | 0c9e39d7e3f425691f854288a733b8d56c5f6ed3 /src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp | |
parent | Merge pull request #640 from lumina-desktop/q5sys-patch-1 (diff) | |
download | lumina-e42bc7e16e6d9f813b5c712261dffbef6b1bddb2.tar.gz lumina-e42bc7e16e6d9f813b5c712261dffbef6b1bddb2.tar.bz2 lumina-e42bc7e16e6d9f813b5c712261dffbef6b1bddb2.zip |
Changes the UI interface so that only the current page is rendered on screen at a time. This has significant memory benefits for large PDF files. This also implements a least-recently used cache of tunable size, which improves responsiveness if you're hopping between two specific pages.
Diffstat (limited to 'src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp')
-rw-r--r-- | src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp | 243 |
1 files changed, 129 insertions, 114 deletions
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp index d6597705..95a32c02 100644 --- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp +++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp @@ -1,23 +1,27 @@ #include "PrintWidget.h" -#include <QPushButton> #include <QGraphicsProxyWidget> +#include <QPushButton> -PrintWidget::PrintWidget(Renderer *backend, QWidget *parent) : - QGraphicsView(parent), scene(0), curPage(1), viewMode(SinglePageView), - zoomMode(FitInView), zoomFactor(1), initialized(false), fitting(true), BACKEND(backend) { +PrintWidget::PrintWidget(Renderer *backend, QWidget *parent) + : QGraphicsView(parent), scene(0), curPage(1), viewMode(SinglePageView), + zoomMode(FitInView), zoomFactor(1), initialized(false), fitting(true), + BACKEND(backend) { this->setMouseTracking(true); - QList<QWidget*> children = this->findChildren<QWidget*>("",Qt::FindChildrenRecursively); - for(int i=0; i<children.length(); i++){ + QList<QWidget *> children = + this->findChildren<QWidget *>("", Qt::FindChildrenRecursively); + for (int i = 0; i < children.length(); i++) { children[i]->setContextMenuPolicy(Qt::CustomContextMenu); - connect(children[i], SIGNAL(customContextMenuRequested(const QPoint&)), this, SIGNAL(customContextMenuRequested(const QPoint&)) ); + QObject::connect(children[i], + SIGNAL(customContextMenuRequested(const QPoint &)), this, + SIGNAL(customContextMenuRequested(const QPoint &))); } this->setInteractive(false); this->setDragMode(QGraphicsView::ScrollHandDrag); this->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); this->setFocusPolicy(Qt::NoFocus); - QObject::connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(updateCurrentPage())); + QObject::connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)), this, + SLOT(updateCurrentPage())); QObject::connect(this, SIGNAL(resized()), this, SLOT(fit())); scene = new QGraphicsScene(this); @@ -31,24 +35,24 @@ PrintWidget::PrintWidget(Renderer *backend, QWidget *parent) : } PrintWidget::~PrintWidget() { - for (int i = 0; i < pages.size(); i++){ + for (int i = 0; i < pages.size(); i++) { scene->removeItem(pages.at(i)); } qDeleteAll(pages); - pages.clear(); + pages.clear(); scene->deleteLater(); } -//Public Slots +// Public Slots void PrintWidget::fitView() { setZoomMode(FitInView); - setCurrentPage(publicPageNum); //Make sure we stay on the same page + setCurrentPage(curPage); // Make sure we stay on the same page } void PrintWidget::fitToWidth() { setZoomMode(FitToWidth); - setCurrentPage(publicPageNum); //Make sure we stay on the same page + setCurrentPage(curPage); // Make sure we stay on the same page } void PrintWidget::setZoomMode(ZoomMode mode) { @@ -57,17 +61,11 @@ void PrintWidget::setZoomMode(ZoomMode mode) { fit(true); } -void PrintWidget::setAllPagesViewMode() { - setViewMode(AllPagesView); -} +void PrintWidget::setAllPagesViewMode() { setViewMode(AllPagesView); } -void PrintWidget::setSinglePageViewMode() { - setViewMode(SinglePageView); -} +void PrintWidget::setSinglePageViewMode() { setViewMode(SinglePageView); } -void PrintWidget::setFacingPagesViewMode() { - setViewMode(FacingPagesView); -} +void PrintWidget::setFacingPagesViewMode() { setViewMode(FacingPagesView); } void PrintWidget::setViewMode(ViewMode mode) { viewMode = mode; @@ -94,7 +92,7 @@ void PrintWidget::zoomOut(double factor) { fitting = false; zoomMode = CustomZoom; zoomFactor *= factor; - this->scale(1/factor, 1/factor); + this->scale(1 / factor, 1 / factor); } void PrintWidget::updatePreview() { @@ -104,48 +102,48 @@ void PrintWidget::updatePreview() { } void PrintWidget::setVisible(bool visible) { - if(visible and !initialized) + if (visible and !initialized) updatePreview(); QGraphicsView::setVisible(visible); } void PrintWidget::setCurrentPage(int pageNumber) { - if(pageNumber < 0 || pageNumber > (pages.count()+1) ){ return; } - publicPageNum = pageNumber; //publicly requested page number (+/- 1 from actual page range) - emit currentPageChanged(); - if(pageNumber < 1 || pageNumber > pages.count()) - return; + int lastPage = curPage; - curPage = pageNumber; + curPage = std::max(1, std::min(pageNumber, BACKEND->numPages())); - if (lastPage != curPage && lastPage > 0 && lastPage <= pages.count()) { + /* if (lastPage != curPage && lastPage > 0 && lastPage <= pages.count()) { if (zoomMode != FitInView) { QScrollBar *hsc = this->horizontalScrollBar(); QScrollBar *vsc = this->verticalScrollBar(); - QPointF pt = this->transform().map(pages.at(curPage-1)->pos()); + QPointF pt = this->transform().map(pages.at(curPage - 1)->pos()); vsc->setValue(int(pt.y()) - 10); hsc->setValue(int(pt.x()) - 10); } else { - this->centerOn(pages.at(curPage-1)); + this->centerOn(pages.at(curPage - 1)); } - } + } */ - //qDebug() << "Page Set"; + if (lastPage != curPage) + updatePreview(); + + qDebug() << "Current page set to " << pageNumber << "\n"; } void PrintWidget::highlightText(TextData *text) { - //Creates a rectangle around the text if the text has not already been highlighted - //qDebug() << "Page:" << text->page() << "Loc:" << text->loc(); - if(!text->highlighted() && !text->loc().isNull()) { + // Creates a rectangle around the text if the text has not already been + // highlighted qDebug() << "Page:" << text->page() << "Loc:" << text->loc(); + if (!text->highlighted() && !text->loc().isNull()) { int degrees = BACKEND->rotatedDegrees(); - //qDebug() << "Degrees:" << degrees; - //Shows the text's location on a non-rotated page + // qDebug() << "Degrees:" << degrees; + // Shows the text's location on a non-rotated page QRectF rect = text->loc(); - //Rotates the rectangle by the page's center and gets the right calculation for text's new location - if(degrees != 0) { - QSize center = BACKEND->imageHash(text->page()-1).size()/2; + // Rotates the rectangle by the page's center and gets the right calculation + // for text's new location + if (degrees != 0) { + QSize center = BACKEND->imageSize(text->page() - 1) / 2; - if(degrees == 90 or degrees == 270) + if (degrees == 90 or degrees == 270) center.transpose(); double cx = center.width(), cy = center.height(); @@ -153,24 +151,24 @@ void PrintWidget::highlightText(TextData *text) { QMatrix matrix; matrix.rotate(BACKEND->rotatedDegrees()); rect = matrix.mapRect(rect); - if(BACKEND->rotatedDegrees() == 180) + if (BACKEND->rotatedDegrees() == 180) rect.adjust(cx, cy, cx, cy); else rect.adjust(cy, cx, cy, cx); } - //qDebug() << "Post Degrees:" << rect; - //Moves the rectangle onto the right page + // qDebug() << "Post Degrees:" << rect; + // Moves the rectangle onto the right page double pageHeight = 0; - for(int i = 0; i < text->page() - 1; i++) + for (int i = 0; i < text->page() - 1; i++) pageHeight += pages.at(i)->boundingRect().height(); - //qDebug() << "PageHeight:" << pageHeight; + // qDebug() << "PageHeight:" << pageHeight; rect.moveTop(rect.y() + pageHeight); - //qDebug() << "Final Rect:" << rect; - //Transparent yellow for the highlight box + // qDebug() << "Final Rect:" << rect; + // Transparent yellow for the highlight box QBrush highlightFill(QColor(255, 255, 177, 100)); QPen highlightOutline(QColor(255, 255, 100, 125)); scene->addRect(rect, highlightOutline, highlightFill); @@ -179,15 +177,17 @@ void PrintWidget::highlightText(TextData *text) { goToPosition(text->page(), text->loc().x(), text->loc().y()); } -//Private functions +// Private functions void PrintWidget::generatePreview() { populateScene(); // i.e. setPreviewPrintedPictures() e.l. layoutPages(); - curPage = qBound(1, curPage, pages.count()); + // curPage = qBound(1, curPage, pages.count()); publicPageNum = curPage; emit currentPageChanged(); - if (fitting){ fit(); } + if (fitting) { + fit(); + } } void PrintWidget::layoutPages() { @@ -197,17 +197,18 @@ void PrintWidget::layoutPages() { int numPagePlaces = numPages; int cols = 1; // singleMode and default - QSize pageSize = BACKEND->imageHash(curPage-1).size(); + QSize pageSize = BACKEND->imageSize(curPage); if (viewMode == AllPagesView) { - cols = pageSize.width() > pageSize.height() ? qFloor(qSqrt(numPages)) : qCeil(qSqrt(numPages)); - cols += cols % 2; // Nicer with an even number of cols + cols = pageSize.width() > pageSize.height() ? qFloor(qSqrt(numPages)) + : qCeil(qSqrt(numPages)); + cols += cols % 2; // Nicer with an even number of cols } else if (viewMode == FacingPagesView) { cols = 2; numPagePlaces += 1; } int rows = qCeil(double(numPagePlaces) / cols); - int pageNum = 0; + int pageNum = 0; QList<double> rowMaxList; for (int i = 0; i < rows && pageNum < numPages; i++) { double rowMax = 0; @@ -215,11 +216,11 @@ void PrintWidget::layoutPages() { double itemWidth = 0, itemHeight = 0; double pageHeight = pages.at(pageNum)->boundingRect().height(); - for(int k = cols * (pageNum / cols); k < pageNum; k++) + for (int k = cols * (pageNum / cols); k < pageNum; k++) itemWidth += pages.at(k)->boundingRect().width(); - foreach(double size, rowMaxList) - itemHeight += size; + foreach (double size, rowMaxList) + itemHeight += size; pages.at(pageNum)->setPos(QPointF(itemWidth, itemHeight)); pageNum++; @@ -228,46 +229,47 @@ void PrintWidget::layoutPages() { rowMaxList.push_back(rowMax); } scene->setSceneRect(scene->itemsBoundingRect()); - //qDebug() << "Finished Page Layout"; + // qDebug() << "Finished Page Layout"; } -void PrintWidget::populateScene() -{ - for (int i = 0; i < pages.size(); i++){ - scene->removeItem(pages.at(i)); - } - qDeleteAll(pages); +void PrintWidget::populateScene() { + // qDeleteAll(scene->items().begin(), scene->items().end()); + scene->clear(); + // qDeleteAll(pages.begin(), pages.end()); pages.clear(); links.clear(); annots.clear(); - int numPages = BACKEND->numPages(); - if(BACKEND->hashSize() < numPages){ return; } //nothing to show yet + // int numPages = BACKEND->numPages(); + if (!BACKEND->isDoneLoading()) { + qDebug() << "populateScene() called while backend still loading.\n"; + return; + } // nothing to show yet - for (int i = 0; i < numPages; i++) { + for (int i = curPage; i < curPage + 1; i++) { QImage pagePicture = BACKEND->imageHash(i); QSize paperSize = pagePicture.size(); - QList<QGraphicsItem*> linkLocations; - QList<QGraphicsItem*> annotLocations; + QList<QGraphicsItem *> linkLocations; + QList<QGraphicsItem *> annotLocations; - if(pagePicture.isNull()) { + if (pagePicture.isNull()) { qDebug() << "NULL IMAGE ON PAGE " << i; continue; } - PageItem* item = new PageItem(i+1, pagePicture, paperSize, BACKEND); + PageItem *item = new PageItem(i + 1, pagePicture, paperSize, BACKEND); scene->addItem(item); pages.append(item); - if(BACKEND->supportsExtraFeatures()) { - for(int k = 0; k < BACKEND->linkSize(i); k++) { + if (BACKEND->supportsExtraFeatures()) { + for (int k = 0; k < BACKEND->linkSize(i); k++) { LinkItem *lItem = new LinkItem(item, BACKEND->linkList(i, k)); lItem->setOpacity(0.1); linkLocations.append(lItem); } - //qDebug() << "Creating annotations for:" << i; - for(int k = 0; k < BACKEND->annotSize(i); k++) { - Annotation *annot = BACKEND->annotList(i, k); - if(annot->getType() == 14) { + // qDebug() << "Creating annotations for:" << i; + for (int k = 0; k < BACKEND->annotSize(i); k++) { + Annotation *annot = BACKEND->annotList(i, k); + if (annot->getType() == 14) { InkItem *iItem = new InkItem(item, annot); annotLocations.append(iItem); } @@ -278,31 +280,38 @@ void PrintWidget::populateScene() annotLocations.append(aZone); } - for(int k = 0; k < BACKEND->widgetSize(i); k++) { + for (int k = 0; k < BACKEND->widgetSize(i); k++) { Widget *widget = BACKEND->widgetList(i, k); int type = widget->getWidgetType(); QRectF loc = widget->getLocation(); QString text = widget->getCurrentText(); - if(type == 0) { + switch (type) { + case 0: { QPushButton *button = new QPushButton(widget->getCurrentText()); button->setGeometry(loc.toRect()); button->setText(text); QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(item); proxy->setWidget(button); - }else if(type == 1) { + } break; + case 1: { - }else if(type == 2) { + } break; + case 2: { - }else if(type == 3) { + } break; + case 3: { - }else if(type == 4) { + } break; + case 4: { - }else if(type == 5) { + } break; + case 5: { - }else if(type == 6) { + } break; + case 6: { - }else { - qDebug() << "INVALID WIDGET"; + } break; + default: { qDebug() << "INVALID WIDGET"; } } } links.insert(i, linkLocations); @@ -311,7 +320,7 @@ void PrintWidget::populateScene() } } -//Private Slots +// Private Slots void PrintWidget::updateCurrentPage() { if (viewMode == AllPagesView) return; @@ -326,12 +335,16 @@ void PrintWidget::updateCurrentPage() { int PrintWidget::calcCurrentPage() { int maxArea = 0; + + return curPage; + int newPage = curPage; QRect viewRect = this->viewport()->rect(); - QList<QGraphicsItem*> items = this->items(viewRect); - for (int i=0; i<items.size(); ++i) { - PageItem* pg = static_cast<PageItem*>(items.at(i)); - QRect overlap = this->mapFromScene(pg->sceneBoundingRect()).boundingRect() & viewRect; + QList<QGraphicsItem *> items = this->items(viewRect); + for (int i = 0; i < items.size(); ++i) { + PageItem *pg = static_cast<PageItem *>(items.at(i)); + QRect overlap = + this->mapFromScene(pg->sceneBoundingRect()).boundingRect() & viewRect; int area = overlap.width() * overlap.height(); if (area > maxArea) { maxArea = area; @@ -352,9 +365,10 @@ void PrintWidget::fit(bool doFitting) { if (doFitting && fitting) { QRect viewRect = this->viewport()->rect(); if (zoomMode == FitInView) { - QList<QGraphicsItem*> containedItems = this->items(viewRect, Qt::ContainsItemBoundingRect); - foreach(QGraphicsItem* item, containedItems) { - PageItem* pg = static_cast<PageItem*>(item); + QList<QGraphicsItem *> containedItems = + this->items(viewRect, Qt::ContainsItemBoundingRect); + foreach (QGraphicsItem *item, containedItems) { + PageItem *pg = static_cast<PageItem *>(item); if (pg->pageNumber() == curPage) return; } @@ -365,7 +379,7 @@ void PrintWidget::fit(bool doFitting) { curPage = newPage; } - QRectF target = pages.at(curPage-1)->sceneBoundingRect(); + QRectF target = pages.at(curPage - 1)->sceneBoundingRect(); if (viewMode == FacingPagesView) { if (curPage % 2) target.setLeft(target.left() - target.width()); @@ -381,7 +395,8 @@ void PrintWidget::fit(bool doFitting) { t.scale(scale, scale); this->setTransform(t); if (doFitting && fitting) { - QRectF viewSceneRect = this->viewportTransform().mapRect(this->viewport()->rect()); + QRectF viewSceneRect = + this->viewportTransform().mapRect(this->viewport()->rect()); viewSceneRect.moveTop(target.top()); this->ensureVisible(viewSceneRect); // Nah... } @@ -398,29 +413,29 @@ void PrintWidget::fit(bool doFitting) { } void PrintWidget::goToPosition(int pagenum, float x, float y) { - //qDebug() << "Page:" << pagenum << "X:" << x << "Y:" << y; + // qDebug() << "Page:" << pagenum << "X:" << x << "Y:" << y; setCurrentPage(pagenum); - + QScrollBar *hsc = this->horizontalScrollBar(); QScrollBar *vsc = this->verticalScrollBar(); - QPointF pt = this->transform().map(pages.at(pagenum-1)->pos()); - int secondPagenum = pagenum < pages.size() ? pagenum : pagenum-2; + QPointF pt = this->transform().map(pages.at(pagenum - 1)->pos()); + int secondPagenum = pagenum < pages.size() ? pagenum : pagenum - 2; QPointF pt2 = this->transform().map(pages.at(secondPagenum)->pos()); - double realHeight = pages.at(pagenum-1)->boundingRect().height(); + double realHeight = pages.at(pagenum - 1)->boundingRect().height(); double virtualHeight = qAbs(pt2.y() - pt.y()); - //qDebug() << "Real:" << realHeight << "Virtual:" << virtualHeight; + // qDebug() << "Real:" << realHeight << "Virtual:" << virtualHeight; - int yConv = int(pt.y() + y*(virtualHeight/realHeight)) - 30; - int xConv = int(pt.x() + x*(virtualHeight/realHeight)) - 30; + int yConv = int(pt.y() + y * (virtualHeight / realHeight)) - 30; + int xConv = int(pt.x() + x * (virtualHeight / realHeight)) - 30; - //qDebug() << "newX:" << xConv << "newY:" << yConv; + // qDebug() << "newX:" << xConv << "newY:" << yConv; - if(yConv > vsc->maximum()) + if (yConv > vsc->maximum()) vsc->triggerAction(QAbstractSlider::SliderToMaximum); - else if(y != 0) + else if (y != 0) vsc->setValue(yConv); - if(x != 0) + if (x != 0) hsc->setValue(xConv); } |