aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/desktop-utils/lumina-pdf
diff options
context:
space:
mode:
authorZackaryWelch <welch.zackary@gmail.com>2017-12-26 18:20:40 -0500
committerZackaryWelch <welch.zackary@gmail.com>2017-12-26 18:20:40 -0500
commita32c6a9fd54fd400db0b729e826bc9a06297a3d7 (patch)
treea2fed348100dd0b36761f86cb020219091085bad /src-qt5/desktop-utils/lumina-pdf
parentMade improvements to focus setting and the find widget in lumina-pdf (diff)
downloadlumina-a32c6a9fd54fd400db0b729e826bc9a06297a3d7.tar.gz
lumina-a32c6a9fd54fd400db0b729e826bc9a06297a3d7.tar.bz2
lumina-a32c6a9fd54fd400db0b729e826bc9a06297a3d7.zip
Began creating custom QPrintPreviewWidget for lumina-pdf
Diffstat (limited to 'src-qt5/desktop-utils/lumina-pdf')
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/CM_PrintPreviewWidget.h34
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp352
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.h114
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro5
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.cpp6
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.h3
6 files changed, 474 insertions, 40 deletions
diff --git a/src-qt5/desktop-utils/lumina-pdf/CM_PrintPreviewWidget.h b/src-qt5/desktop-utils/lumina-pdf/CM_PrintPreviewWidget.h
deleted file mode 100644
index ac457a10..00000000
--- a/src-qt5/desktop-utils/lumina-pdf/CM_PrintPreviewWidget.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===========================================
-// Lumina Desktop source code
-// Copyright (c) 2017, Ken Moore
-// Available under the 3-clause BSD license
-// See the LICENSE file for full details
-//===========================================
-// Simple subclass of QPrintPreviewWidget to provide
-// notification when a context menu is requested
-//===========================================
-#ifndef _CONTEXT_MENU_PRINT_PREVIEW_WIDGET_H
-#define _CONTEXT_MENU_PRINT_PREVIEW_WIDGET_H
-
-#include <QPrintPreviewWidget>
-#include <QMouseEvent>
-#include <QDebug>
-
-class CM_PrintPreviewWidget : public QPrintPreviewWidget{
- Q_OBJECT
-signals:
- void customContextMenuRequested(const QPoint&);
-
-public:
- CM_PrintPreviewWidget(QPrinter * printer = 0, QWidget *parent = 0) : QPrintPreviewWidget(printer, parent){
- this->setMouseTracking(true);
- 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&)) );
- }
- }
-
-};
-
-#endif
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
new file mode 100644
index 00000000..3fa87367
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
@@ -0,0 +1,352 @@
+#include "PrintWidget.h"
+
+class PageItem : public QGraphicsItem
+{
+public:
+ PageItem(int _pageNum, const QPicture* _pagePicture, QSize _paperSize, QRect _pageRect)
+ : pageNum(_pageNum), pagePicture(_pagePicture),
+ paperSize(_paperSize), pageRect(_pageRect)
+ {
+ qreal border = qMax(paperSize.height(), paperSize.width()) / 25;
+ brect = QRectF(QPointF(-border, -border),
+ QSizeF(paperSize)+QSizeF(2*border, 2*border));
+ setCacheMode(DeviceCoordinateCache);
+ }
+
+ QRectF boundingRect() const Q_DECL_OVERRIDE
+ { return brect; }
+
+ inline int pageNumber() const
+ { return pageNum; }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) Q_DECL_OVERRIDE;
+
+private:
+ int pageNum;
+ const QPicture* pagePicture;
+ QSize paperSize;
+ QRect pageRect;
+ QRectF brect;
+};
+
+void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(widget);
+
+ 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);
+ if (!pagePicture)
+ return;
+ painter->drawPicture(pageRect.topLeft(), *pagePicture);
+
+ // Effect: make anything drawn in the margins look washed out.
+ QPainterPath path;
+ path.addRect(paperRect);
+ path.addRect(pageRect);
+ painter->setPen(QPen(Qt::NoPen));
+ painter->setBrush(QColor(255, 255, 255, 180));
+ painter->drawPath(path);
+}
+PrintWidget::PrintWidget(QPrinter *printer, QWidget *parent) : QWidget(parent), scene(0), curPage(1), viewMode(SinglePageView), zoomMode(FitInView), zoomFactor(1), initialized(false), fitting(true) {
+ this->printer = printer;
+ this->setMouseTracking(true);
+ 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&)) );
+ }
+ graphicsView = new GraphicsView;
+ graphicsView->setInteractive(false);
+ graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
+ graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
+ QObject::connect(graphicsView->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(updateCurrentPage()));
+ QObject::connect(graphicsView, SIGNAL(resized()), this, SLOT(fit()));
+
+ scene = new QGraphicsScene(graphicsView);
+ scene->setBackgroundBrush(Qt::gray);
+ graphicsView->setScene(scene);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ setLayout(layout);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(graphicsView);
+}
+
+PrintWidget::~PrintWidget() {
+ //Nothing here for now
+}
+
+//Public Slots
+
+void PrintWidget::fitInView() {
+ setZoomMode(FitToWidth);
+}
+
+void PrintWidget::fitToWidget() {
+ setZoomMode(FitInView);
+}
+
+void PrintWidget::setZoomMode(ZoomMode mode) {
+ zoomMode = mode;
+ fitting = true;
+ fit(true);
+}
+
+void PrintWidget::setAllPagesViewMode() {
+ setViewMode(AllPagesView);
+}
+
+void PrintWidget::setSinglePageViewMode() {
+ setViewMode(SinglePageView);
+}
+
+void PrintWidget::setFacingPagesViewMode() {
+ setViewMode(FacingPagesView);
+}
+
+void PrintWidget::setViewMode(ViewMode mode) {
+ viewMode = mode;
+ layoutPages();
+ if (viewMode == AllPagesView) {
+ graphicsView->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+ fitting = false;
+ zoomMode = CustomZoom;
+ zoomFactor = graphicsView->transform().m11() * (double(printer->logicalDpiY()) / logicalDpiY());
+ emit previewChanged();
+ } else {
+ fitting = true;
+ fit();
+ }
+}
+
+void PrintWidget::zoomIn(double factor) {
+ fitting = false;
+ zoomMode = CustomZoom;
+ zoomFactor *= factor;
+ graphicsView->scale(factor, factor);
+}
+
+void PrintWidget::zoomOut(double factor) {
+ fitting = false;
+ zoomMode = CustomZoom;
+ zoomFactor *= factor;
+ graphicsView->scale(1/factor, 1/factor);
+}
+
+void PrintWidget::updatePreview() {
+ initialized = true;
+ generatePreview();
+ graphicsView->updateGeometry();
+}
+
+void PrintWidget::setOrientation(QPrinter::Orientation orientation) {
+ printer->setOrientation(orientation);
+ generatePreview();
+}
+
+void PrintWidget::setVisible(bool visible) {
+ if(visible and !initialized)
+ updatePreview();
+ QWidget::setVisible(visible);
+}
+
+void PrintWidget::setCurrentPage(int pageNumber) {
+ if(pageNumber < 1 || pageNumber > pages.count())
+ return;
+
+ int lastPage = curPage;
+ curPage = pageNumber;
+
+ if (lastPage != curPage && lastPage > 0 && lastPage <= pages.count()) {
+ if (zoomMode != FitInView) {
+ QScrollBar *hsc = graphicsView->horizontalScrollBar();
+ QScrollBar *vsc = graphicsView->verticalScrollBar();
+ QPointF pt = graphicsView->transform().map(pages.at(curPage-1)->pos());
+ vsc->setValue(int(pt.y()) - 10);
+ hsc->setValue(int(pt.x()) - 10);
+ } else {
+ graphicsView->centerOn(pages.at(curPage-1));
+ }
+ }
+}
+
+//Private functions
+
+void PrintWidget::generatePreview() {
+ //printer->d_func()->setPreviewMode(true);
+ emit paintRequested(printer);
+ //printer->d_func()->setPreviewMode(false);
+ //pictures = printer->previewPages();
+ populateScene(); // i.e. setPreviewPrintedPictures() e.l.
+ layoutPages();
+ curPage = qBound(1, curPage, pages.count());
+ if (fitting)
+ fit();
+ emit previewChanged();
+}
+
+void PrintWidget::layoutPages() {
+ int numPages = pages.count();
+ if (numPages < 1)
+ return;
+
+ int numPagePlaces = numPages;
+ int cols = 1; // singleMode and default
+ if (viewMode == AllPagesView) {
+ if (printer->orientation() == QPrinter::Portrait)
+ cols = qCeil(qSqrt(numPages));
+ else
+ cols = qFloor(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);
+
+ double itemWidth = pages.at(0)->boundingRect().width();
+ double itemHeight = pages.at(0)->boundingRect().height();
+ int pageNum = 1;
+ for (int i = 0; i < rows && pageNum <= numPages; i++) {
+ for (int j = 0; j < cols && pageNum <= numPages; j++) {
+ if (!i && !j && viewMode == FacingPagesView) {
+ continue;
+ } else {
+ pages.at(pageNum-1)->setPos(QPointF(j*itemWidth, i*itemHeight));
+ pageNum++;
+ }
+ }
+ }
+ scene->setSceneRect(scene->itemsBoundingRect());
+}
+
+void PrintWidget::populateScene()
+{
+ for (int i = 0; i < pages.size(); i++)
+ scene->removeItem(pages.at(i));
+ qDeleteAll(pages);
+ pages.clear();
+
+ int numPages = pictures.count();
+ QSize paperSize = printer->pageLayout().fullRectPixels(printer->resolution()).size();
+ QRect pageRect = printer->pageLayout().paintRectPixels(printer->resolution());
+
+ for (int i = 0; i < numPages; i++) {
+ PageItem* item = new PageItem(i+1, pictures.at(i), paperSize, pageRect);
+ scene->addItem(item);
+ pages.append(item);
+ }
+}
+
+
+//Private Slots
+void PrintWidget::updateCurrentPage() {
+ if (viewMode == AllPagesView)
+ return;
+
+ int newPage = calcCurrentPage();
+ if (newPage != curPage) {
+ curPage = newPage;
+ emit previewChanged();
+ }
+}
+
+int PrintWidget::calcCurrentPage() {
+ int maxArea = 0;
+ int newPage = curPage;
+ QRect viewRect = graphicsView->viewport()->rect();
+ QList<QGraphicsItem*> items = graphicsView->items(viewRect);
+ for (int i=0; i<items.size(); ++i) {
+ PageItem* pg = static_cast<PageItem*>(items.at(i));
+ QRect overlap = graphicsView->mapFromScene(pg->sceneBoundingRect()).boundingRect() & viewRect;
+ int area = overlap.width() * overlap.height();
+ if (area > maxArea) {
+ maxArea = area;
+ newPage = pg->pageNumber();
+ } else if (area == maxArea && pg->pageNumber() < newPage) {
+ newPage = pg->pageNumber();
+ }
+ }
+ return newPage;
+}
+
+void PrintWidget::fit(bool doFitting) {
+ if (curPage < 1 || curPage > pages.count())
+ return;
+ if (!doFitting && !fitting)
+ return;
+
+ if (doFitting && fitting) {
+ QRect viewRect = graphicsView->viewport()->rect();
+ if (zoomMode == FitInView) {
+ QList<QGraphicsItem*> containedItems = graphicsView->items(viewRect, Qt::ContainsItemBoundingRect);
+ foreach(QGraphicsItem* item, containedItems) {
+ PageItem* pg = static_cast<PageItem*>(item);
+ if (pg->pageNumber() == curPage)
+ return;
+ }
+ }
+
+ int newPage = calcCurrentPage();
+ if (newPage != curPage)
+ curPage = newPage;
+ }
+
+ QRectF target = pages.at(curPage-1)->sceneBoundingRect();
+ if (viewMode == FacingPagesView) {
+ if (curPage % 2)
+ target.setLeft(target.left() - target.width());
+ else
+ target.setRight(target.right() + target.width());
+ } else if (viewMode == AllPagesView) {
+ target = scene->itemsBoundingRect();
+ }
+
+ if (zoomMode == FitToWidth) {
+ QTransform t;
+ qreal scale = graphicsView->viewport()->width() / target.width();
+ t.scale(scale, scale);
+ graphicsView->setTransform(t);
+ if (doFitting && fitting) {
+ QRectF viewSceneRect = graphicsView->viewportTransform().mapRect(graphicsView->viewport()->rect());
+ viewSceneRect.moveTop(target.top());
+ graphicsView->ensureVisible(viewSceneRect); // Nah...
+ }
+ } else {
+ graphicsView->fitInView(target, Qt::KeepAspectRatio);
+ if (zoomMode == FitInView) {
+ int step = qRound(graphicsView->matrix().mapRect(target).height());
+ graphicsView->verticalScrollBar()->setSingleStep(step);
+ graphicsView->verticalScrollBar()->setPageStep(step);
+ }
+ }
+
+ zoomFactor = graphicsView->transform().m11() * (float(printer->logicalDpiY()) / this->logicalDpiY());
+ emit previewChanged();
+}
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
new file mode 100644
index 00000000..061aef49
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
@@ -0,0 +1,114 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// Simple subclass of QPrintPreviewWidget to provide
+// notification when a context menu is requested
+//===========================================
+#ifndef _PRINT_PREVIEW_WIDGET_H
+#define _PRINT_PREVIEW_WIDGET_H
+
+#include <QMouseEvent>
+#include <QDebug>
+#include <QGraphicsView>
+#include <QGraphicsItem>
+#include <QBoxLayout>
+#include <QScrollBar>
+#include <QStyleOptionGraphicsItem>
+#include <QtMath>
+#include <QPrinter>
+
+class GraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ GraphicsView(QWidget *parent = 0) : QGraphicsView(parent) { }
+signals:
+ void resized();
+protected:
+ void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE {
+ /*{
+ const QSignalBlocker blocker(verticalScrollBar()); // Don't change page, QTBUG-14517
+ QGraphicsView::resizeEvent(e);
+ }*/
+ QGraphicsView::resizeEvent(e);
+ emit resized();
+ }
+
+ void showEvent(QShowEvent* e) Q_DECL_OVERRIDE {
+ QGraphicsView::showEvent(e);
+ emit resized();
+ }
+};
+
+class PrintWidget: public QWidget{
+ Q_OBJECT
+public:
+ enum ViewMode {
+ SinglePageView,
+ FacingPagesView,
+ AllPagesView
+ };
+
+ enum ZoomMode {
+ CustomZoom,
+ FitToWidth,
+ FitInView
+ };
+
+ PrintWidget(QPrinter *printer = 0, QWidget *parent = 0);
+ ~PrintWidget();
+
+ int currentPage() const { return curPage; };
+ double getZoomFactor() const { return this->zoomFactor; };
+ QPrinter::Orientation orientation() const { return printer->orientation(); };
+ ZoomMode getZoomMode() const { return this->zoomMode; };
+ void setVisible(bool);
+
+public slots:
+ void zoomIn(double factor=1.2);
+ void zoomOut(double factor=1.2);
+ void setOrientation(QPrinter::Orientation);
+ void setCurrentPage(int);
+
+ void fitInView();
+ void fitToWidget();
+ void setAllPagesViewMode();
+ void setSinglePageViewMode();
+ void setFacingPagesViewMode();
+
+ void updatePreview();
+
+private slots:
+ void updateCurrentPage();
+ int calcCurrentPage();
+ void fit(bool doFitting=false);
+
+signals:
+ void customContextMenuRequested(const QPoint&);
+ void paintRequested(QPrinter*);
+ void previewChanged();
+
+private:
+ void generatePreview();
+ void layoutPages();
+ void populateScene();
+ void setViewMode(ViewMode viewMode);
+ void setZoomMode(ZoomMode viewMode);
+
+ QPrinter *printer;
+ GraphicsView *graphicsView;
+ QGraphicsScene *scene;
+ int curPage;
+ QList<const QPicture *> pictures;
+ QList<QGraphicsItem *> pages;
+
+ ViewMode viewMode;
+ ZoomMode zoomMode;
+ double zoomFactor;
+ bool initialized, fitting;
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro b/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro
index 3a031067..8ee67d06 100644
--- a/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro
+++ b/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro
@@ -19,10 +19,11 @@ message("Qt Modules Needed: $${QT}")
SOURCES += main.cpp \
mainUI.cpp \
- propDialog.cpp
+ propDialog.cpp \
+ PrintWidget.cpp
HEADERS += mainUI.h \
- CM_PrintPreviewWidget.h \
+ PrintWidget.h \
PresentationLabel.h \
PropDialog.h
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp b/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
index c5de3015..6c5b762c 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
@@ -21,7 +21,7 @@
#include <QtConcurrent>
#include <LuminaXDG.h>
-#include "CM_PrintPreviewWidget.h"
+#include "PrintWidget.h"
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
ui->setupUi(this);
@@ -33,7 +33,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
lastdir = QDir::homePath();
Printer = new QPrinter();
//Create the interface widgets
- WIDGET = new CM_PrintPreviewWidget(Printer,this);
+ WIDGET = new PrintWidget(Printer,this);
clockTimer = new QTimer(this);
clockTimer->setInterval(1000); //1-second updates to clock
connect(clockTimer, SIGNAL(timeout()), this, SLOT(updateClock()) );
@@ -53,7 +53,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
WIDGET->setContextMenuPolicy(Qt::CustomContextMenu);
connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(newFocus(QWidget*, QWidget*)));
connect(WIDGET, SIGNAL(customContextMenuRequested(const QPoint&)),this, SLOT(showContextMenu(const QPoint&)) );
- connect(WIDGET, &QPrintPreviewWidget::paintRequested, this,
+ connect(WIDGET, &PrintWidget::paintRequested, this,
[=](QPrinter *printer) { this->paintOnWidget(printer, this->highlight); });
DOC = 0;
connect(this, SIGNAL(PageLoaded(int)), this, SLOT(slotPageLoaded(int)) );
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.h b/src-qt5/desktop-utils/lumina-pdf/mainUI.h
index 60a1beb9..cce04cd4 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.h
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.h
@@ -22,6 +22,7 @@
#include <poppler/qt5/poppler-qt5.h>
#include "PresentationLabel.h"
#include "propDialog.h"
+#include "PrintWidget.h"
namespace Ui{
class MainUI;
@@ -37,7 +38,7 @@ public:
private:
Poppler::Document *DOC;
- QPrintPreviewWidget *WIDGET;
+ PrintWidget *WIDGET;
Ui::MainUI *ui;
PropDialog *PROPDIALOG;
QPrinter* Printer;
bgstack15