From e42bc7e16e6d9f813b5c712261dffbef6b1bddb2 Mon Sep 17 00:00:00 2001 From: joe berner Date: Tue, 18 Dec 2018 10:59:15 -0600 Subject: 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. --- src-qt5/desktop-utils/lumina-pdf/PrintWidget.h | 273 +++++-------------------- 1 file changed, 48 insertions(+), 225 deletions(-) (limited to 'src-qt5/desktop-utils/lumina-pdf/PrintWidget.h') diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h index 8e365a99..1240d140 100644 --- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h +++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h @@ -10,208 +10,27 @@ #ifndef _PRINT_GRAPHICS_H #define _PRINT_GRAPHICS_H -#include +#include "Renderer.h" +#include "TextData.h" +#include "graphicsitems.h" +#include +#include #include -#include #include -#include +#include +#include +#include #include #include -#include -#include #include -#include -#include "Renderer.h" -#include "TextData.h" - -class InkItem: public QGraphicsItem { -public: - InkItem(QGraphicsItem *parent, Annotation *_annot) : QGraphicsItem(parent), pointData(_annot->getInkList()), inkColor(_annot->getColor()), annot(_annot) { - setCacheMode(DeviceCoordinateCache); - bbox = annot->getLoc(); - } - - QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE - { - Q_UNUSED(widget); - painter->setClipRect(option->exposedRect); - QPen inkPen = QPen(inkColor); - painter->setPen(inkPen); - foreach(QVector pointList, pointData) { - painter->drawLines(pointList); - } - } - -private: - QRectF bbox; - QVector> pointData; - QColor inkColor; - Annotation *annot; -}; - -class PopupItem: public QGraphicsItem { -public: - PopupItem(QGraphicsItem *parent, Annotation *_annot) : QGraphicsItem(parent), author(_annot->getAuthor()), text(_annot->getText()) { - QRectF loc = _annot->getLoc(); - setCacheMode(DeviceCoordinateCache); - QString allText = "Author: " + author + "\n\n" + text; - QTextDocument document; - document.setDefaultFont(QFont("Helvitica", 10, QFont::Normal)); - document.setPageSize(QSize(120, 120)); - document.setHtml(allText); - loc.moveTopLeft(QPointF(loc.center().x(), loc.center().y()+loc.height()/2)); - loc.setSize(document.size()+QSize(10, 10)); - bbox = loc; - } - - QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE - { - Q_UNUSED(widget); - QString allText = "Author: " + author + "\n\n" + text; - painter->setClipRect(option->exposedRect); - painter->setFont(QFont("Helvitica", 10, QFont::Normal)); - painter->setBrush(QBrush(QColor(255, 255, 177, 255))); - painter->drawRect(bbox); - painter->setPen(QPen(QColor("Black"))); - painter->drawText(bbox, Qt::AlignLeft | Qt::TextWordWrap, allText); - } - -private: - QRectF bbox; - QString author; - QString text; -}; - -class AnnotZone: public QGraphicsItem { -public: - AnnotZone(QGraphicsItem *parent, Annotation *_annot, PopupItem *_annotItem) : QGraphicsItem(parent), bbox(_annot->getLoc()), annot(_annotItem) { - _hasText = !_annot->getText().isEmpty(); - _hasAuthor = !_annot->getAuthor().isEmpty(); - } - - QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; } - PopupItem* annotation() const { return annot; } - bool hasText() const { return _hasText; } - bool hasAuthor() const { return _hasAuthor; } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE { Q_UNUSED(widget); Q_UNUSED(painter); Q_UNUSED(option); } - -private: - QRectF bbox; - PopupItem *annot; - bool _hasText; - bool _hasAuthor; -}; - -class LinkItem: public QGraphicsItem { -public: - LinkItem(QGraphicsItem *parent, TextData *_data) : QGraphicsItem(parent), bbox(_data->loc()), data(_data) { - setCacheMode(DeviceCoordinateCache); - setAcceptHoverEvents(true); - } - -QRectF boundingRect() const Q_DECL_OVERRIDE - { return bbox; } - -inline TextData* getData() const - { return data; } - -void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE -{ - Q_UNUSED(widget); - painter->setClipRect(option->exposedRect); - painter->setBrush(QBrush(QColor(255, 255, 177, 100))); - painter->setPen(QPen(QColor(255, 255, 100, 125))); - painter->drawRect(bbox); -} - -private: - QRectF bbox; - TextData *data; -}; - -class PageItem : public QGraphicsItem { -public: - PageItem(int _pageNum, QImage _pagePicture, QSize _paperSize, Renderer *_backend) - : pageNum(_pageNum), pagePicture(_pagePicture), paperSize(_paperSize), BACKEND(_backend) - { - brect = QRectF(QPointF(-25, -25), - QSizeF(paperSize)+QSizeF(50, 50)); - setCacheMode(DeviceCoordinateCache); - setAcceptHoverEvents(true); - } - - QRectF boundingRect() const Q_DECL_OVERRIDE - { return brect; } - - inline int pageNumber() const - { return pageNum; } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE - { - Q_UNUSED(widget); - //Ensure all the antialiasing/smoothing options are turned on - painter->setRenderHint(QPainter::Antialiasing); - painter->setRenderHint(QPainter::TextAntialiasing); - painter->setRenderHint(QPainter::SmoothPixmapTransform); - - QRectF paperRect(0,0, paperSize.width(), paperSize.height()); - // Draw shadow - painter->setClipRect(option->exposedRect); - qreal shWidth = paperRect.width()/100; - QRectF rshadow(paperRect.topRight() + QPointF(0, shWidth), - paperRect.bottomRight() + QPointF(shWidth, 0)); - QLinearGradient rgrad(rshadow.topLeft(), rshadow.topRight()); - rgrad.setColorAt(0.0, QColor(0,0,0,255)); - rgrad.setColorAt(1.0, QColor(0,0,0,0)); - painter->fillRect(rshadow, QBrush(rgrad)); - QRectF bshadow(paperRect.bottomLeft() + QPointF(shWidth, 0), - paperRect.bottomRight() + QPointF(0, shWidth)); - QLinearGradient bgrad(bshadow.topLeft(), bshadow.bottomLeft()); - bgrad.setColorAt(0.0, QColor(0,0,0,255)); - bgrad.setColorAt(1.0, QColor(0,0,0,0)); - painter->fillRect(bshadow, QBrush(bgrad)); - QRectF cshadow(paperRect.bottomRight(), - paperRect.bottomRight() + QPointF(shWidth, shWidth)); - QRadialGradient cgrad(cshadow.topLeft(), shWidth, cshadow.topLeft()); - cgrad.setColorAt(0.0, QColor(0,0,0,255)); - cgrad.setColorAt(1.0, QColor(0,0,0,0)); - painter->fillRect(cshadow, QBrush(cgrad)); - painter->setClipRect(paperRect & option->exposedRect); - painter->fillRect(paperRect, Qt::white); - painter->drawImage(QPoint(0,0), pagePicture); - for(int k = 0; k < BACKEND->annotSize(pageNum-1); k++) { - Annotation *annot = BACKEND->annotList(pageNum-1, k); - painter->drawImage(annot->getLoc(), annot->renderImage()); - } - } - -private: - int pageNum; - QImage pagePicture; - QSize paperSize; - QRectF brect; - Renderer *BACKEND; -}; +#include -class PrintWidget : public QGraphicsView -{ +class PrintWidget : public QGraphicsView { Q_OBJECT public: - enum ViewMode { - SinglePageView, - FacingPagesView, - AllPagesView - }; + enum ViewMode { SinglePageView, FacingPagesView, AllPagesView }; - enum ZoomMode { - CustomZoom, - FitToWidth, - FitInView - }; + enum ZoomMode { CustomZoom, FitToWidth, FitInView }; private: void generatePreview(); @@ -227,9 +46,9 @@ private: QPageLayout::Orientation orientation; double zoomFactor; bool initialized, fitting; - QList pages; - QHash> links; - QHash> annots; + QList pages; + QHash> links; + QHash> annots; int degrees; Renderer *BACKEND; @@ -237,21 +56,24 @@ public: PrintWidget(Renderer *backend, QWidget *parent = 0); ~PrintWidget(); - double getZoomFactor() const { return this->zoomFactor; }; - ZoomMode getZoomMode() const { return this->zoomMode; }; - int currentPage() const { return publicPageNum; }; + double getZoomFactor() const { return this->zoomFactor; } + ZoomMode getZoomMode() const { return this->zoomMode; } + int currentPage() const { + return curPage; + return publicPageNum; + } signals: void resized(); - void customContextMenuRequested(const QPoint&); + void customContextMenuRequested(const QPoint &); void currentPageChanged(); public slots: - void zoomIn(double factor=1.2); - void zoomOut(double factor=1.2); + void zoomIn(double factor = 1.2); + void zoomOut(double factor = 1.2); void setCurrentPage(int); void setVisible(bool) Q_DECL_OVERRIDE; - void highlightText(TextData*); + void highlightText(TextData *); void goToPosition(int, float, float); void updatePreview(); @@ -264,25 +86,25 @@ public slots: private slots: void updateCurrentPage(); int calcCurrentPage(); - void fit(bool doFitting=false); + void fit(bool doFitting = false); protected: - void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE { + void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE { /*{ - const QSignalBlocker blocker(verticalScrollBar()); // Don't change page, QTBUG-14517 - QGraphicsView::resizeEvent(e); + const QSignalBlocker blocker(verticalScrollBar()); // Don't change page, + QTBUG-14517 QGraphicsView::resizeEvent(e); }*/ QGraphicsView::resizeEvent(e); emit resized(); - } + } - void clearItems(QList itemList, QGraphicsItem *item) { - foreach(QGraphicsItem *graphicsItem, itemList) { - if(item == graphicsItem) + void clearItems(QList itemList, QGraphicsItem *item) { + foreach (QGraphicsItem *graphicsItem, itemList) { + if (item == graphicsItem) continue; - if(graphicsItem == dynamic_cast(graphicsItem)) + if (graphicsItem == dynamic_cast(graphicsItem)) graphicsItem->setOpacity(0.1); - if(graphicsItem == dynamic_cast(graphicsItem)) + if (graphicsItem == dynamic_cast(graphicsItem)) graphicsItem->setVisible(false); } } @@ -291,28 +113,29 @@ protected: QGraphicsView::mouseMoveEvent(e); static bool cursorSet = false; - if(QGraphicsItem *item = scene->itemAt(mapToScene(e->pos()), transform())) { - QList linkList; - if(item == dynamic_cast(item)) + if (QGraphicsItem *item = + scene->itemAt(mapToScene(e->pos()), transform())) { + QList linkList; + if (item == dynamic_cast(item)) item = item->parentItem(); - if(PageItem *page = dynamic_cast(item)) + if (PageItem *page = dynamic_cast(item)) linkList = page->childItems(); - else if(item != dynamic_cast(item)) + else if (item != dynamic_cast(item)) linkList = item->parentItem()->childItems(); - if(LinkItem *link = dynamic_cast(item)){ + if (LinkItem *link = dynamic_cast(item)) { item->setOpacity(1); - if(!cursorSet) { + if (!cursorSet) { QApplication::setOverrideCursor(QCursor(Qt::PointingHandCursor)); cursorSet = true; } - }else if(cursorSet){ + } else if (cursorSet) { QApplication::restoreOverrideCursor(); cursorSet = false; } - if(AnnotZone *annotZone = dynamic_cast(item)){ - if(annotZone->hasText() or annotZone->hasAuthor()) + if (AnnotZone *annotZone = dynamic_cast(item)) { + if (annotZone->hasText() or annotZone->hasAuthor()) annotZone->annotation()->setVisible(true); item = annotZone->annotation(); } @@ -324,13 +147,13 @@ protected: QGraphicsView::mouseReleaseEvent(e); QPointF scenePoint = mapToScene(e->pos()); QGraphicsItem *item = scene->itemAt(scenePoint, transform()); - if(LinkItem *link = dynamic_cast(item)) { + if (LinkItem *link = dynamic_cast(item)) { BACKEND->handleLink(this, link->getData()->text()); link->setOpacity(0.1); } } - void showEvent(QShowEvent* e) Q_DECL_OVERRIDE { + void showEvent(QShowEvent *e) Q_DECL_OVERRIDE { QGraphicsView::showEvent(e); emit resized(); } -- cgit