aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmkport.sh3
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp48
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h34
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_fi.ts2
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_it.ts4
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_ja.ts26
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp16
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp133
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp4
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/Renderer.h4
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.cpp12
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.h1
12 files changed, 191 insertions, 96 deletions
diff --git a/mkport.sh b/mkport.sh
index 2d9d9e0d..5ebd9bce 100755
--- a/mkport.sh
+++ b/mkport.sh
@@ -6,9 +6,6 @@
dfile="lumina"
VERSION="1.4.2"
-#Debugging of build failures
-exit 1
-
massage_subdir() {
cd "$1"
if [ $? -ne 0 ] ; then
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp
new file mode 100644
index 00000000..24ad3fda
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp
@@ -0,0 +1,48 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2018, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "NativeWindow.h"
+
+// === PUBLIC ===
+NativeWindow::NativeWindow( NativeWindowObject *obj ) : QFrame(0, Qt::Window | Qt::FramelessWindowHint){
+ WIN = obj;
+ createFrame();
+}
+
+NativeWindow::~NativeWindow(){
+
+}
+
+// === PRIVATE ===
+void NativeWindow::createFrame(){
+ //Initialize the widgets
+ closeB = new QToolButton(this);
+ closeB->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ minB = new QToolButton(this);
+ minB->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ maxB = new QToolButton(this);
+ maxB->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ otherB = new QToolButton(this);
+ otherB->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ toolbarL = new QHBoxLayout(this);
+ vlayout = new QVBoxLayout(this);
+ vlayout.align
+ titleLabel = new QLabel(this);
+ titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ //Now put the widgets in the right places
+ toolbarL->addWidget(otherB);
+ toolbarL->addWidget(titleLabel);
+ toolbarL->addWidget(minB);
+ toolbarL->addWidget(maxB);
+ toolbarL->addWidget(closeB);
+ vlayout->addLayout(toolbarL);
+ vlayout->addStretch();
+ this->setLayout(vlayout);
+
+ //
+}
+
+// === PRIVATE SLOTS ===
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h
new file mode 100644
index 00000000..ffdb364a
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h
@@ -0,0 +1,34 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2018, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_DESKTOP_NATIVE_WINDOW_WIDGET_H
+#define _LUMINA_DESKTOP_NATIVE_WINDOW_WIDGET_H
+
+#include <global-includes.h>
+
+class NativeWindow : public QFrame{
+ Q_OBJECT
+public:
+ NativeWindow(NativeWindowObject *obj);
+ ~NativeWindow();
+
+private:
+ //Core object
+ NativeWindowObject *WIN;
+ // Interface items
+ void createFrame();
+ QToolButton *closeB, *minB, *maxB, *otherB;
+ QHBoxLayout *toolbarL;
+ QVBoxLayout *vlayout;
+ QLabel *titleLabel;
+ // Info cache variables
+ QRect oldgeom;
+
+private slots:
+
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_fi.ts b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_fi.ts
index 1b8a54c8..2e29e77c 100644
--- a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_fi.ts
+++ b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_fi.ts
@@ -66,7 +66,7 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation>Lajittelematta</translation>
+ <translation>Lajittelemattomat</translation>
</message>
</context>
<context>
diff --git a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_it.ts b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_it.ts
index 3136f945..6ed76f82 100644
--- a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_it.ts
+++ b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_it.ts
@@ -11,7 +11,7 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Sviluppo</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
@@ -26,7 +26,7 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Grafica</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
diff --git a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_ja.ts b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_ja.ts
index 28c70ada..5f0fabe6 100644
--- a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_ja.ts
+++ b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_ja.ts
@@ -80,7 +80,7 @@
<message>
<location filename="../mainUI.ui" line="657"/>
<source>Advanced Operations</source>
- <translation type="unfinished">高度な演算</translation>
+ <translation>高度な計算</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="83"/>
@@ -90,22 +90,22 @@
<message>
<location filename="../mainUI.cpp" line="85"/>
<source>Power %1</source>
- <translation type="unfinished">冪 %1</translation>
+ <translation>べき乗 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="87"/>
<source>Base-10 Exponential %1</source>
- <translation type="unfinished"></translation>
+ <translation>10が底の指数関数 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="89"/>
<source>Exponential %1</source>
- <translation type="unfinished">指数 %1</translation>
+ <translation>指数関数 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="91"/>
<source>Constant Pi %1</source>
- <translation type="unfinished">円周率 %1</translation>
+ <translation>円周率π %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="94"/>
@@ -125,7 +125,7 @@
<message>
<location filename="../mainUI.cpp" line="101"/>
<source>Sine %1</source>
- <translation type="unfinished">正弦 %1</translation>
+ <translation>正弦 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="103"/>
@@ -140,37 +140,37 @@
<message>
<location filename="../mainUI.cpp" line="108"/>
<source>Arc Sine %1</source>
- <translation type="unfinished">Arc Sine %1</translation>
+ <translation>逆正弦 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="110"/>
<source>Arc Cosine %1</source>
- <translation type="unfinished">Arc Cosine %1</translation>
+ <translation>逆余弦 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="112"/>
<source>Arc Tangent %1</source>
- <translation type="unfinished">Arc Tangent %1</translation>
+ <translation>逆正接 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="115"/>
<source>Hyperbolic Sine %1</source>
- <translation type="unfinished">Hyperbolic Sine %1</translation>
+ <translation>双曲線正弦 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="117"/>
<source>Hyperbolic Cosine %1</source>
- <translation type="unfinished">Hyperbolic Cosine %1</translation>
+ <translation>双曲線余弦 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="119"/>
<source>Hyperbolic Tangent %1</source>
- <translation type="unfinished">Hyperbolic Tangent %1</translation>
+ <translation>双曲線正接 %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="182"/>
<source>Save Calculator History</source>
- <translation type="unfinished">電卓の歴史を保存</translation>
+ <translation>計算履歴を保存</translation>
</message>
</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
index bece454e..5c7fa1dd 100644
--- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
@@ -185,23 +185,23 @@ void PrintWidget::layoutPages() {
void PrintWidget::populateScene()
{
for (int i = 0; i < pages.size(); i++){
- scene->removeItem(pages.at(i));
+ scene->removeItem(pages.at(i));
}
qDeleteAll(pages);
pages.clear();
//qDebug() << "populateScene";
if(pictures==0){ return; } //nothing to show yet
int numPages = pictures->count();
- //Replace from loadingHash resolution
- QSize paperSize = pictures->value(0).size();
- //qDebug() << "Image paperSize" << paperSize;
-
- //Changes the paper orientation if rotated by 90 or 270 degrees
- if(degrees == 90 or degrees == 270)
- paperSize.transpose();
for (int i = 0; i < numPages; i++) {
QImage pagePicture = pictures->value(i);
+
+ QSize paperSize = pictures->value(i).size();
+
+ //Changes the paper orientation if rotated by 90 or 270 degrees
+ if(degrees == 90 or degrees == 270)
+ paperSize.transpose();
+
if(degrees != 0) {
pagePicture = pagePicture.transformed(rotMatrix, Qt::SmoothTransformation);
//qDebug() << "Rotating by: " << degrees << " degrees";
diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp b/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp
index 279888c6..799f6584 100644
--- a/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp
@@ -1,23 +1,43 @@
#include "Renderer.h"
-#include <mupdf/fitz.h>
-#include <mupdf/pdf.h>
-
#include <QDateTime>
+#include <mupdf/fitz.h>
+//#include <pthread.h>
fz_document *DOC;
-pdf_document *PDOC;
fz_context *CTX;
-inline QString getTextInfo(pdf_obj *info, QString str) {
- pdf_obj *obj = pdf_dict_gets(CTX, info, str.toLatin1().data());
- if(obj){ return pdf_to_utf8(CTX, obj); }
+inline QString getTextInfo(QString str) {
+ char infoBuff[1000];
+ int size = DOC->lookup_metadata(CTX, DOC, ("info:"+str).toLocal8Bit().data(), infoBuff, 1000);
+ if(size != -1){ return QString::fromLatin1(infoBuff); }
return "";
}
+/*void lock_mutex(void *user, int lock) {
+ pthread_mutex_t *mutex = (pthread_mutex_t *) user;
+ pthread_mutex_lock(&mutex[lock]);
+}
+
+void unlock_mutex(void *user, int lock) {
+ pthread_mutex_t *mutex = (pthread_mutex_t *) user;
+ pthread_mutex_unlock(&mutex[lock]);
+}*/
+
Renderer::Renderer(){
+ /*pthread_mutex_t mutex[FZ_LOCK_MAX];
+ fz_locks_context locks;
+ locks.user = mutex;
+ locks.lock = lock_mutex;
+ locks.unlock = unlock_mutex;
+
+ for (int i = 0; i < FZ_LOCK_MAX; i++)
+ pthread_mutex_init(&mutex[i], NULL);*/
+
+ mutex = new QMutex();
DOC = 0;
+ //CTX = fz_new_context(NULL, &locks, FZ_STORE_UNLIMITED);
CTX = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
- PDOC = 0;
+ qDebug() << "Context created";
needpass = false;
}
@@ -25,43 +45,45 @@ Renderer::~Renderer(){
}
-bool Renderer::loadMultiThread(){ return false; }
+//bool Renderer::loadMultiThread(){ return true; }
QJsonObject Renderer::properties(){
QJsonObject jobj;
- pdf_obj *info = pdf_dict_gets(CTX, pdf_trailer(CTX, PDOC), "Info");
- jobj.insert("title", getTextInfo(info, "Title") );
- jobj.insert("subject", getTextInfo(info, "Subject") );
- jobj.insert("author", getTextInfo(info, "Author") );
- jobj.insert("creator", getTextInfo(info, "Creator") );
- jobj.insert("producer", getTextInfo(info, "Producer") );
- jobj.insert("keywords", getTextInfo(info, "Keywords") );
- jobj.insert("dt_created", QDateTime::fromString( getTextInfo(info, "CreationDate").left(16), "'D:'yyyyMMddHHmmss").toString() );
- jobj.insert("dt_modified", QDateTime::fromString( getTextInfo(info, "ModDate").left(16), "'D:'yyyyMMddHHmmss").toString() );
+ jobj.insert("title", getTextInfo("Title") );
+ jobj.insert("subject", getTextInfo("Subject") );
+ jobj.insert("author", getTextInfo("Author") );
+ jobj.insert("creator", getTextInfo("Creator") );
+ jobj.insert("producer", getTextInfo("Producer") );
+ jobj.insert("keywords", getTextInfo("Keywords") );
+ jobj.insert("dt_created", QDateTime::fromString( getTextInfo("CreationDate").left(16), "'D:'yyyyMMddHHmmss").toString() );
+ jobj.insert("dt_modified", QDateTime::fromString( getTextInfo("ModDate").left(16), "'D:'yyyyMMddHHmmss").toString() );
return jobj;
}
bool Renderer::loadDocument(QString path, QString password){
- if(DOC==0){ fz_register_document_handlers(CTX); } //first time through
- else if(path!=docpath){
+ //first time through
+ if(DOC==0){
+ fz_register_document_handlers(CTX);
+ qDebug() << "Document handlers registered";
+ }else if(path!=docpath){
//fz_close_document(DOC);
//Clear out the old document first
delete DOC;
DOC=0;
- if(PDOC!=0){ delete PDOC; PDOC=0; }
needpass = false;
+ docpath = path;
}
+
if(DOC==0){
DOC = fz_open_document(CTX, path.toLocal8Bit().data());
+ docpath = path;
+ qDebug() << "File opened";
if(DOC==0){
qDebug() << "Could not open file:" << path;
return false;
}
needpass = (fz_needs_password(CTX, DOC) != 0);
}
- if(PDOC==0){
- PDOC = pdf_open_document(CTX, path.toLocal8Bit().data());
- }
if(needpass && password.isEmpty()){ return false; }
else if(needpass){
@@ -69,48 +91,47 @@ bool Renderer::loadDocument(QString path, QString password){
if(needpass){ return false; } //incorrect password
}
+ qDebug() << "Password Check cleared";
+
//Could read/access the PDF - go ahead and load the info now
pnum = -1;
doctitle.clear();
//qDebug() << "Opening File:" << path;
- pdf_obj *info = pdf_dict_gets(CTX, pdf_trailer(CTX, (pdf_document*)DOC), "Info");
- if(info) {
- if(pdf_obj *obj = pdf_dict_gets(CTX, info, (char *)"Title")){ doctitle = pdf_to_utf8(CTX, obj); }
- }
- if(doctitle.isEmpty()){ doctitle = path.section("/",-1); }
+ QString title = getTextInfo("Subject");
+ if(!title.isNull())
+ doctitle = title;
+ else
+ doctitle = path.section("/",-1);
pnum = fz_count_pages(CTX, DOC);
//Setup the Document
fz_page *PAGE = fz_load_page(CTX, DOC, 0);
- if(PAGE!=0){
- /*switch(PAGE->orientation()){
- case Poppler::Page::Landscape:
- WIDGET->setOrientation(QPageLayout::Landscape); break;
- default:
- WIDGET->setOrientation(QPageLayout::Portrait);
- }*/
- delete PAGE;
- return true; //could see the first page
- }
- return false;
+ qDebug() << "Page Loaded";
+ //Possibly check Page orientation";
+
+ return (PAGE);
}
+//Consider rendering through a display list
QImage Renderer::renderPage(int pagenum, QSize DPI){
- //MuPDF uses a scaling factor, not DPI
- fz_page *PAGE = fz_load_page(CTX, DOC, pagenum);
- QImage img;
- if(PAGE!=0){
- fz_matrix matrix;
- //double scaleFactorW = dpi.width()/72.0;
- //double scaleFactorH = dpi.height()/72.0;
- //fz_scale(&matrix, scaleFactorW, scaleFactorH);
- fz_scale(&matrix, 4.0, 4.0); //need to adjust this later according to DPI
- fz_pre_rotate(&matrix, 0.0);
- fz_pixmap *pixmap = fz_new_pixmap_from_page_number(CTX, DOC, pagenum, &matrix, fz_device_rgb(CTX), 0);
- //unsigned char *samples = fz_pixmap_samples(CTX, pixmap);
- img = QImage(pixmap->samples, pixmap->w, pixmap->h, QImage::Format_RGB888); //make the raw image a bit larger than the end result
- delete PAGE;
- }
- qDebug() << "Render Page:" << pagenum << img.size();
+ QImage img;
+ fz_matrix matrix;
+ fz_pixmap *pixmap = nullptr;
+
+ fz_scale(&matrix, DPI.width()/96.0, DPI.height()/96.0);
+
+ //fz_context *ctx = fz_clone_context(CTX);
+ mutex->lock();
+
+ fz_try(CTX) {
+ pixmap = fz_new_pixmap_from_page_number(CTX, DOC, pagenum, &matrix, fz_device_rgb(CTX), 0);
+ }fz_catch(CTX){
+ qDebug() << "Error when rendering page using MuPDF";
+ }
+
+ mutex->unlock();
+
+ img = QImage(pixmap->samples, pixmap->w, pixmap->h, pixmap->stride, QImage::Format_RGB888);
+ qDebug() << "Render Page:" << pagenum;
return img;
}
diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp b/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp
index b2d7dd32..693faa64 100644
--- a/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp
@@ -13,7 +13,7 @@ Renderer::~Renderer(){
}
-bool Renderer::loadMultiThread(){ return true; }
+//bool Renderer::loadMultiThread(){ return true; }
QJsonObject Renderer::properties(){
return QJsonObject(); //TO-DO
@@ -27,11 +27,13 @@ bool Renderer::loadDocument(QString path, QString password){
DOC=0;
needpass = false;
pnum=0;
+ docpath = path;
}
//Load the Document (if needed);
if(DOC==0){
//qDebug() << "Loading Document";
DOC = Poppler::Document::load(path);
+ docpath = path;
}
if(DOC==0){
diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer.h b/src-qt5/desktop-utils/lumina-pdf/Renderer.h
index 09e9c425..c9e13c7f 100644
--- a/src-qt5/desktop-utils/lumina-pdf/Renderer.h
+++ b/src-qt5/desktop-utils/lumina-pdf/Renderer.h
@@ -11,6 +11,7 @@
#include <QImage>
#include <QDebug>
#include <QJsonObject>
+#include <QMutex>
#include "textData.h"
class Renderer{
@@ -19,10 +20,11 @@ private:
bool needpass;
QString docpath; //save the path for the currently-loaded document
QString doctitle;
+ QMutex *mutex;
public:
Renderer();
~Renderer();
- bool loadMultiThread();
+ //bool loadMultiThread();
//Information functions (usually needs to be loaded first)
int numPages(){ return pnum; }
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp b/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
index 5262c875..54b281dd 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
@@ -15,7 +15,6 @@
#include <QDebug>
#include <QApplication>
#include <QScreen>
-#include <QTimer>
#include <iostream>
#include <QtConcurrent>
@@ -382,10 +381,6 @@ void MainUI::startLoadingPages(){
// Using Qt to scale the image (adjust page value) smooths out the image quite a bit without a lot of performance loss (but cannot scale up without pixelization)
// The best approach seams to be to increase the DPI a bit, but match that with the same scaling on the page size (smoothing)
- //double scalefactor = 2.5;
- //fz_rect page_rect;
- //fz_bound_page(CTX, fz_load_page(CTX, DOC, 0), &page_rect);
- //pageSize = QSizeF((page_rect.x1 - page_rect.x0)/72.0, (page_rect.y1 - page_rect.y0)/72.0);
QSize DPI(300,300); //print-quality (some printers even go to 600 DPI nowdays)
/*qDebug() << "Screen Resolutions:";
@@ -393,14 +388,9 @@ void MainUI::startLoadingPages(){
for(int i=0; i<screens.length(); i++){
qDebug() << screens[i]->name() << screens[i]->logicalDotsPerInchX() << screens[i]->logicalDotsPerInchY();
}*/
- bool async = BACKEND->loadMultiThread();
for(int i=0; i<BACKEND->numPages(); i++){
//qDebug() << " - Kickoff page load:" << i;
- if(async){
- QtConcurrent::run(this, &MainUI::loadPage, i, this, DPI);
- }else{
- loadPage(i, this, DPI);
- }
+ QtConcurrent::run(this, &MainUI::loadPage, i, this, DPI);
}
//qDebug() << "Finish page loading kickoff";
}
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.h b/src-qt5/desktop-utils/lumina-pdf/mainUI.h
index 911456aa..74badbfd 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.h
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.h
@@ -18,6 +18,7 @@
#include <QWheelEvent>
#include <QApplication>
#include <QMenu>
+#include <QTimer>
#include "Renderer.h"
#include "PresentationLabel.h"
bgstack15