gui: stop generating preview images after a memory limit has been reached.
This commit is contained in:
parent
5deb64cd28
commit
330a9e5870
@ -116,32 +116,35 @@ void MainWindow::tabChanged()
|
|||||||
|
|
||||||
void MainWindow::pdfPreviewReceived(PdfPreview preview)
|
void MainWindow::pdfPreviewReceived(PdfPreview preview)
|
||||||
{
|
{
|
||||||
ClickLabel *label = new ClickLabel();
|
if(preview.hasPreviewImage())
|
||||||
label->setPixmap(QPixmap::fromImage(preview.previewImage));
|
{
|
||||||
label->setToolTip(preview.documentPath);
|
ClickLabel *label = new ClickLabel();
|
||||||
ui->scrollAreaWidgetContents->layout()->addWidget(label);
|
label->setPixmap(QPixmap::fromImage(preview.previewImage));
|
||||||
connect(label, &ClickLabel::leftClick,
|
label->setToolTip(preview.documentPath);
|
||||||
[=]()
|
ui->scrollAreaWidgetContents->layout()->addWidget(label);
|
||||||
{
|
connect(label, &ClickLabel::leftClick,
|
||||||
QSettings settings;
|
[=]()
|
||||||
QString command = settings.value("pdfviewer").toString();
|
|
||||||
if(command != "" && command.contains("%p") && command.contains("%f"))
|
|
||||||
{
|
{
|
||||||
command = command.replace("%f", preview.documentPath);
|
QSettings settings;
|
||||||
command = command.replace("%p", QString::number(preview.page));
|
QString command = settings.value("pdfviewer").toString();
|
||||||
QStringList splitted = command.split(" ");
|
if(command != "" && command.contains("%p") && command.contains("%f"))
|
||||||
if(splitted.size() > 1)
|
|
||||||
{
|
{
|
||||||
QString cmd = splitted[0];
|
command = command.replace("%f", preview.documentPath);
|
||||||
QStringList args = splitted.mid(1);
|
command = command.replace("%p", QString::number(preview.page));
|
||||||
QProcess::startDetached(cmd, args);
|
QStringList splitted = command.split(" ");
|
||||||
|
if(splitted.size() > 1)
|
||||||
|
{
|
||||||
|
QString cmd = splitted[0];
|
||||||
|
QStringList args = splitted.mid(1);
|
||||||
|
QProcess::startDetached(cmd, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
QDesktopServices::openUrl(QUrl::fromLocalFile(preview.documentPath));
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(preview.documentPath));
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::lineEditReturnPressed()
|
void MainWindow::lineEditReturnPressed()
|
||||||
@ -179,14 +182,9 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
|||||||
item->setText(0, fileName);
|
item->setText(0, fileName);
|
||||||
item->setText(1, result.fileData.absPath);
|
item->setText(1, result.fileData.absPath);
|
||||||
item->setText(2, dt.toString(Qt::ISODate));
|
item->setText(2, dt.toString(Qt::ISODate));
|
||||||
|
if(result.fileData.absPath.endsWith(".pdf"))
|
||||||
// TODO: this must be user defined or done more intelligently
|
|
||||||
if(this->pdfSearchResults.size() < 300)
|
|
||||||
{
|
{
|
||||||
if(result.fileData.absPath.endsWith(".pdf"))
|
this->pdfSearchResults.append(result);
|
||||||
{
|
|
||||||
this->pdfSearchResults.append(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ui->treeResultsList->resizeColumnToContents(0);
|
ui->treeResultsList->resizeColumnToContents(0);
|
||||||
|
@ -9,6 +9,11 @@ class PdfPreview
|
|||||||
QImage previewImage;
|
QImage previewImage;
|
||||||
QString documentPath;
|
QString documentPath;
|
||||||
unsigned int page;
|
unsigned int page;
|
||||||
|
|
||||||
|
bool hasPreviewImage()
|
||||||
|
{
|
||||||
|
return !previewImage.isNull();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PDFPREVIEW_H
|
#endif // PDFPREVIEW_H
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <QtConcurrent/QtConcurrentMap>
|
#include <QtConcurrent/QtConcurrentMap>
|
||||||
|
#include <atomic>
|
||||||
#include "pdfworker.h"
|
#include "pdfworker.h"
|
||||||
|
|
||||||
static QMutex cacheMutex;
|
static QMutex cacheMutex;
|
||||||
@ -16,10 +17,22 @@ struct Renderer
|
|||||||
double scaleX;
|
double scaleX;
|
||||||
double scaleY;
|
double scaleY;
|
||||||
QHash<QString, Poppler::Document *> documentcache;
|
QHash<QString, Poppler::Document *> documentcache;
|
||||||
Renderer(double scaleX, double scaleY)
|
qsizetype maxTotalPreviewImageMemUsage;
|
||||||
|
std::atomic<qsizetype> currentTotalPreviewImageMemUsage{0};
|
||||||
|
|
||||||
|
Renderer(double scaleX, double scaleY, qsizetype maxPreviewImageMemUsage)
|
||||||
{
|
{
|
||||||
this->scaleX = scaleX;
|
this->scaleX = scaleX;
|
||||||
this->scaleY = scaleY;
|
this->scaleY = scaleY;
|
||||||
|
this->maxTotalPreviewImageMemUsage = maxPreviewImageMemUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*we need this one because std::atomic has none, but this is only a functor for
|
||||||
|
concurrentmap, thus, it's ok for it to be half-broken*/
|
||||||
|
Renderer(const Renderer &o)
|
||||||
|
{
|
||||||
|
this->scaleX = o.scaleX;
|
||||||
|
this->scaleY = o.scaleY;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Renderer()
|
~Renderer()
|
||||||
@ -35,7 +48,7 @@ struct Renderer
|
|||||||
Poppler::Document *result = Poppler::Document::load(path);
|
Poppler::Document *result = Poppler::Document::load(path);
|
||||||
if(result == nullptr)
|
if(result == nullptr)
|
||||||
{
|
{
|
||||||
// TODO: some kind of user feedback would be nicec
|
// TODO: some kind of user feedback would be nice
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
result->setRenderHint(Poppler::Document::TextAntialiasing);
|
result->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||||
@ -46,23 +59,28 @@ struct Renderer
|
|||||||
|
|
||||||
PdfPreview operator()(const PdfPreview &preview)
|
PdfPreview operator()(const PdfPreview &preview)
|
||||||
{
|
{
|
||||||
Poppler::Document *doc = document(preview.documentPath);
|
|
||||||
if(doc == nullptr)
|
|
||||||
{
|
|
||||||
return preview;
|
|
||||||
}
|
|
||||||
if(doc->isLocked())
|
|
||||||
{
|
|
||||||
return preview;
|
|
||||||
}
|
|
||||||
int p = (int)preview.page - 1;
|
|
||||||
if(p < 0)
|
|
||||||
{
|
|
||||||
p = 0;
|
|
||||||
}
|
|
||||||
Poppler::Page *pdfPage = doc->page(p);
|
|
||||||
PdfPreview result = preview;
|
PdfPreview result = preview;
|
||||||
result.previewImage = pdfPage->renderToImage(scaleX, scaleY);
|
if(currentTotalPreviewImageMemUsage.load() < maxTotalPreviewImageMemUsage)
|
||||||
|
{
|
||||||
|
Poppler::Document *doc = document(preview.documentPath);
|
||||||
|
if(doc == nullptr)
|
||||||
|
{
|
||||||
|
return preview;
|
||||||
|
}
|
||||||
|
if(doc->isLocked())
|
||||||
|
{
|
||||||
|
return preview;
|
||||||
|
}
|
||||||
|
int p = (int)preview.page - 1;
|
||||||
|
if(p < 0)
|
||||||
|
{
|
||||||
|
p = 0;
|
||||||
|
}
|
||||||
|
Poppler::Page *pdfPage = doc->page(p);
|
||||||
|
QImage img = pdfPage->renderToImage(scaleX, scaleY);
|
||||||
|
result.previewImage = img;
|
||||||
|
currentTotalPreviewImageMemUsage += img.sizeInBytes();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -85,5 +103,8 @@ QFuture<PdfPreview> PdfWorker::generatePreviews(const QVector<SearchResult> path
|
|||||||
double scaleX = QGuiApplication::primaryScreen()->physicalDotsPerInchX() * scalefactor;
|
double scaleX = QGuiApplication::primaryScreen()->physicalDotsPerInchX() * scalefactor;
|
||||||
double scaleY = QGuiApplication::primaryScreen()->physicalDotsPerInchY() * scalefactor;
|
double scaleY = QGuiApplication::primaryScreen()->physicalDotsPerInchY() * scalefactor;
|
||||||
|
|
||||||
return QtConcurrent::mapped(previews, Renderer(scaleX, scaleY));
|
QSettings setting;
|
||||||
|
qsizetype maxPreviewImageMemUsage = setting.value("maxpreviewimagesmemory", 1024 * 1024 * 1024).toLongLong();
|
||||||
|
|
||||||
|
return QtConcurrent::mapped(previews, Renderer(scaleX, scaleY, maxPreviewImageMemUsage));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user