Skip to content

Commit 63feda6

Browse files
committed
use big boy threads
addresses #28
1 parent de75279 commit 63feda6

5 files changed

+92
-39
lines changed

ImageViewer.cpp

+47-14
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <QMovie>
3131
#include <QPainter>
3232
#include <QScrollBar>
33+
#include <QThread>
3334
#include <QTimer>
3435
#include <QWheelEvent>
3536

@@ -602,6 +603,13 @@ void ImageViewer::setImage(const QImage &image) {
602603
}
603604

604605
void ImageViewer::reload() {
606+
static bool s_busy = false;
607+
static bool s_abort = false;
608+
if (s_busy) {
609+
s_abort = true;
610+
QMetaObject::invokeMethod(this, "reload", Qt::QueuedConnection);
611+
return;
612+
}
605613
if (Settings::showImageName) {
606614
if (fullImagePath.left(1) == ":") {
607615
setInfo("No Image");
@@ -666,23 +674,48 @@ void ImageViewer::reload() {
666674
viewerImage = origImage = m_preloadedImage;
667675
m_preloadedImage = QImage();
668676
m_preloadedPath.clear();
669-
} else if (imageReader.size().isValid() && imageReader.read(&origImage)) {
670-
if (Settings::exifRotationEnabled) {
671-
m_exifTransformation = Metadata::transformation(fullImagePath);
672-
origImage = origImage.transformed(Metadata::transformation(fullImagePath), Qt::SmoothTransformation);
677+
} else if (imageReader.size().isValid()) {
678+
bool imageOk = false;
679+
if (batchMode || Settings::slideShowActive) {
680+
imageReader.read(&origImage);
681+
} else {
682+
QThread *thread = QThread::create([&](){imageOk = imageReader.read(&origImage);});
683+
thread->start();
684+
s_busy = true;
685+
while (!thread->wait(30)) {
686+
QApplication::processEvents();
687+
if (s_abort) {
688+
thread->terminate();
689+
thread->wait();
690+
break;
691+
}
692+
}
693+
s_busy = false;
694+
thread->deleteLater();
695+
if (s_abort) {
696+
s_abort = false;
697+
return;
698+
}
673699
}
674-
viewerImage = origImage;
675700

676-
if (Settings::colorsActive || Settings::keepTransform) {
677-
colorize();
678-
}
679-
if (myMirrorLayout) {
680-
mirror();
681-
}
682-
} else {
683-
viewerImage = QIcon::fromTheme("image-missing",
701+
if (imageOk) {
702+
if (Settings::exifRotationEnabled) {
703+
m_exifTransformation = Metadata::transformation(fullImagePath);
704+
origImage = origImage.transformed(Metadata::transformation(fullImagePath), Qt::SmoothTransformation);
705+
}
706+
viewerImage = origImage;
707+
708+
if (Settings::colorsActive || Settings::keepTransform) {
709+
colorize();
710+
}
711+
if (myMirrorLayout) {
712+
mirror();
713+
}
714+
} else {
715+
viewerImage = QIcon::fromTheme("image-missing",
684716
QIcon(":/images/error_image.png")).pixmap(BAD_IMAGE_SIZE, BAD_IMAGE_SIZE).toImage();
685-
setInfo(QFileInfo(imageReader.fileName()).fileName() + ": " + imageReader.errorString());
717+
setInfo(QFileInfo(imageReader.fileName()).fileName() + ": " + imageReader.errorString());
718+
}
686719
}
687720

688721
setImage(viewerImage);

ImageViewer.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ Q_OBJECT
6161
void loadImage(QString imageFileName, const QImage &preview = QImage());
6262
void preload(QString imageFileName);
6363
void refresh();
64-
void reload();
6564
void resizeImage(QPoint focus = QPoint(-1, -1));
6665
void scaleImage(QSize newSize);
6766
void setBackgroundColor();
@@ -81,13 +80,13 @@ Q_OBJECT
8180
void toolsUpdated();
8281

8382
public slots:
84-
83+
void applyCropAndRotation();
8584
void monitorCursorState();
8685
void saveImage();
8786
void saveImageAs();
8887
void copyImage();
8988
void pasteImage();
90-
void applyCropAndRotation();
89+
void reload();
9190

9291
private slots:
9392

Phototonic.cpp

+18-10
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#include <QStandardPaths>
4343
#include <QStandardItemModel>
4444
#include <QStatusBar>
45-
#include <QThreadPool>
45+
#include <QThread>
4646
#include <QToolBar>
4747
#include <QToolButton>
4848
#include <QToolTip>
@@ -273,7 +273,10 @@ void Phototonic::createImageViewer() {
273273
connect(copyImageAction, SIGNAL(triggered()), imageViewer, SLOT(copyImage()));
274274
connect(pasteImageAction, SIGNAL(triggered()), imageViewer, SLOT(pasteImage()));
275275
connect(imageViewer, &ImageViewer::toolsUpdated, [=](){ rotateToolAction->setChecked(Settings::mouseRotateEnabled); });
276-
connect(imageViewer, &ImageViewer::gotFocus, [=](){ thumbsViewer->setCurrentIndex(imageViewer->fullImagePath); });
276+
connect(imageViewer, &ImageViewer::gotFocus, [=](){
277+
if (thumbsViewer->selectionModel()->selectedIndexes().size() < 1)
278+
thumbsViewer->setCurrentIndex(imageViewer->fullImagePath);
279+
});
277280
QMenu *contextMenu = new QMenu(imageViewer);
278281

279282
// Widget actions
@@ -1892,6 +1895,10 @@ void Phototonic::loadCurrentImage(int currentRow) {
18921895
}
18931896

18941897
void Phototonic::deleteImages(bool trash) { // Deleting selected thumbnails
1898+
if (thumbsViewer->isBusy()) { // defer, don't alter while the thumbsviewer is loading stuff
1899+
QTimer::singleShot(100, this, [=](){deleteImages(trash);});
1900+
return;
1901+
}
18951902
ASSERT_IMAGES_SELECTED
18961903

18971904
QStringList deathRow;
@@ -1914,10 +1921,6 @@ void Phototonic::deleteImages(bool trash) { // Deleting selected thumbnails
19141921
}
19151922
}
19161923

1917-
// wait until thumbnail loading is done
1918-
while (QThreadPool::globalInstance()->activeThreadCount())
1919-
QThreadPool::globalInstance()->waitForDone(-1);
1920-
19211924
// To only show progress dialog if deleting actually takes time
19221925
QElapsedTimer timer;
19231926
timer.start();
@@ -1999,10 +2002,15 @@ void Phototonic::deleteFromViewer(bool trash) {
19992002
return;
20002003
}
20012004

2002-
if (Settings::slideShowActive) {
2005+
if (Settings::slideShowActive) { // needs to happen now
20032006
toggleSlideShow();
20042007
}
2005-
imageViewer->setCursorHiding(false);
2008+
imageViewer->setCursorHiding(false); // tells that sth. is happening
2009+
2010+
if (thumbsViewer->isBusy()) { // defer, don't alter while the thumbsviewer is loading stuff
2011+
QTimer::singleShot(100, this, [=](){deleteFromViewer(trash);});
2012+
return;
2013+
}
20062014

20072015
const QString fullPath = imageViewer->fullImagePath;
20082016
const QString fileName = QFileInfo(fullPath).fileName();
@@ -2021,8 +2029,8 @@ void Phototonic::deleteFromViewer(bool trash) {
20212029
return;
20222030
}
20232031
}
2024-
while (QThreadPool::globalInstance()->activeThreadCount())
2025-
QThreadPool::globalInstance()->waitForDone(-1);
2032+
while (thumbsViewer->isBusy())
2033+
QThread::sleep(30);
20262034

20272035
QString trashError;
20282036
if (trash ? (Trash::moveToTrash(fullPath, trashError) == Trash::Success) :

ThumbsViewer.cpp

+24-12
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <QScrollBar>
3434
#include <QStandardItemModel>
3535
#include <QStandardPaths>
36-
#include <QThreadPool>
36+
#include <QThread>
3737
#include <QTimer>
3838
#include <QTreeWidget>
3939
#include <cmath>
@@ -363,8 +363,7 @@ void ThumbsViewer::loadFileList() {
363363
}
364364

365365
void ThumbsViewer::reLoad() {
366-
if (m_busy || QThreadPool::globalInstance()->activeThreadCount()) {
367-
QThreadPool::globalInstance()->clear();
366+
if (m_busy) {
368367
abort();
369368
QTimer::singleShot(50, this, [=]() { reLoad(); });
370369
return;
@@ -380,8 +379,6 @@ void ThumbsViewer::reLoad() {
380379
disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), scrollDelay, SLOT(start()));
381380
m_busy = true;
382381

383-
QThreadPool::globalInstance()->waitForDone(-1);
384-
385382
histFiles.clear(); // these can grow out of control and currently sort O(n^2)
386383
histograms.clear();
387384
m_histSorted = false;
@@ -669,8 +666,7 @@ void ThumbsViewer::refreshThumbs() {
669666

670667
void ThumbsViewer::loadDuplicates()
671668
{
672-
if (m_busy || QThreadPool::globalInstance()->activeThreadCount()) {
673-
QThreadPool::globalInstance()->clear();
669+
if (m_busy) {
674670
abort();
675671
QTimer::singleShot(50, this, [=]() { loadDuplicates(); });
676672
return;
@@ -1132,8 +1128,7 @@ void ThumbsViewer::loadThumbsRange() {
11321128
continue;
11331129

11341130
if (!loadThumb(currThumb, true)) {
1135-
QThreadPool::globalInstance()->start([=](){loadThumb(currThumb);});
1136-
// qDebug() << "slow image read"; loadThumb(currThumb);
1131+
loadThumb(currThumb);
11371132
}
11381133

11391134
if (timer.elapsed() > 30) {
@@ -1294,6 +1289,17 @@ bool ThumbsViewer::loadThumb(int currThumb, bool fastOnly) {
12941289
if (fastOnly && shouldStoreThumbnail)
12951290
return false;
12961291

1292+
auto readThreaded = [&]() {
1293+
bool wentOk = false;
1294+
QThread *thread = QThread::create([&](){wentOk = thumbReader.read(&thumb);});
1295+
thread->start();
1296+
while (!thread->wait(30)) {
1297+
QApplication::processEvents();
1298+
}
1299+
thread->deleteLater();
1300+
return wentOk;
1301+
};
1302+
12971303
QSize thumbSizeQ(thumbSize,thumbSize);
12981304
if (currentThumbSize.isValid()) {
12991305
bool scaleMe = Settings::upscalePreview ||
@@ -1304,7 +1310,7 @@ bool ThumbsViewer::loadThumb(int currThumb, bool fastOnly) {
13041310
}
13051311

13061312
thumbReader.setScaledSize(currentThumbSize);
1307-
imageReadOk = thumbReader.read(&thumb);
1313+
imageReadOk = readThreaded();
13081314

13091315
if (imageReadOk && !shouldStoreThumbnail) {
13101316
int w = thumb.text("Thumb::Image::Width").toInt();
@@ -1319,7 +1325,7 @@ bool ThumbsViewer::loadThumb(int currThumb, bool fastOnly) {
13191325
if (!imageReadOk && !shouldStoreThumbnail) { // tried thumbnail but somehow failed, sanitize it
13201326
shouldStoreThumbnail = true;
13211327
thumbReader.setFileName(imageFileName);
1322-
imageReadOk = thumbReader.read(&thumb);
1328+
imageReadOk = readThreaded();
13231329
}
13241330
}
13251331

@@ -1391,7 +1397,13 @@ QStandardItem * ThumbsViewer::addThumb(const QString &imageFullPath) {
13911397
}
13921398

13931399
thumbReader.setScaledSize(currThumbSize);
1394-
QImage thumb = thumbReader.read();
1400+
QImage thumb;
1401+
QThread *thread = QThread::create([&](){thumbReader.read(&thumb);});
1402+
thread->start();
1403+
while (!thread->wait(30)) {
1404+
QApplication::processEvents();
1405+
}
1406+
thread->deleteLater();
13951407

13961408
if (Settings::exifThumbRotationEnabled) {
13971409
thumb = thumb.transformed(Metadata::transformation(imageFullPath), Qt::SmoothTransformation);

ThumbsViewer.h

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ Q_OBJECT
141141
int lastVisibleThumb();
142142
QImage renderHistogram(const QString &imagePath, bool logarithmic = false);
143143
QString locateThumbnail(const QString &path) const;
144+
bool isBusy() { return m_busy; }
144145

145146
ImageTags *imageTags;
146147
QDir thumbsDir;

0 commit comments

Comments
 (0)