diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp index 2949d83d9..cbff1489c 100644 --- a/core/imagedownloader.cpp +++ b/core/imagedownloader.cpp @@ -140,7 +140,8 @@ QImage getHashedImage(const QString &file) return res; } -Thumbnailer::Thumbnailer() +Thumbnailer::Thumbnailer() : failImage(QImage(":filter-close").scaled(maxThumbnailSize(), maxThumbnailSize(), Qt::KeepAspectRatio)), // TODO: Don't misuse filter close icon + dummyImage(QImage(":photo-icon").scaled(maxThumbnailSize(), maxThumbnailSize(), Qt::KeepAspectRatio)) // TODO: Don't misuse photo-icon { // Currently, we only process one image at a time. Stefan Fuchs reported problems when // calculating multiple thumbnails at once and this hopefully helps. @@ -200,16 +201,16 @@ static void addThumbnailToCache(const QImage &thumbnail, const QString &picture_ file.commit(); } -void Thumbnailer::processItem(QString filename, int size) +void Thumbnailer::processItem(QString filename) { QImage thumbnail = getThumbnailFromCache(filename); if (thumbnail.isNull()) { thumbnail = getHashedImage(filename); if (thumbnail.isNull()) { - // TODO: Don't misuse filter close icon - thumbnail = QImage(":filter-close").scaled(size, size, Qt::KeepAspectRatio); + thumbnail = failImage; } else { + int size = maxThumbnailSize(); thumbnail = thumbnail.scaled(size, size, Qt::KeepAspectRatio); addThumbnailToCache(thumbnail, filename); } @@ -220,7 +221,7 @@ void Thumbnailer::processItem(QString filename, int size) workingOn.remove(filename); } -QImage Thumbnailer::fetchThumbnail(PictureEntry &entry, int size) +QImage Thumbnailer::fetchThumbnail(PictureEntry &entry) { QMutexLocker l(&lock); @@ -228,9 +229,9 @@ QImage Thumbnailer::fetchThumbnail(PictureEntry &entry, int size) const QString &filename = entry.filename; if (!workingOn.contains(filename)) { workingOn.insert(filename, - QtConcurrent::run(&pool, [this, filename, size]() { processItem(filename, size); })); + QtConcurrent::run(&pool, [this, filename]() { processItem(filename); })); } - return QImage(":photo-icon").scaled(size, size, Qt::KeepAspectRatio); + return dummyImage; } void Thumbnailer::clearWorkQueue() @@ -240,3 +241,27 @@ void Thumbnailer::clearWorkQueue() it->cancel(); workingOn.clear(); } + +static const int maxZoom = 3; // Maximum zoom: thrice of standard size + +int Thumbnailer::defaultThumbnailSize() +{ + return defaultIconMetrics().sz_pic; +} + +int Thumbnailer::maxThumbnailSize() +{ + return defaultThumbnailSize() * maxZoom; +} + +int Thumbnailer::thumbnailSize(double zoomLevel) +{ + // Calculate size of thumbnails. The standard size is defaultIconMetrics().sz_pic. + // We use exponential scaling so that the central point is the standard + // size and the minimum and maximum extreme points are a third respectively + // three times the standard size. + // Naturally, these three zoom levels are then represented by + // -1.0 (minimum), 0 (standard) and 1.0 (maximum). The actual size is + // calculated as standard_size*3.0^zoomLevel. + return static_cast(round(defaultThumbnailSize() * pow(maxZoom, zoomLevel))); +} diff --git a/core/imagedownloader.h b/core/imagedownloader.h index d8e9d2d7d..92edea0b6 100644 --- a/core/imagedownloader.h +++ b/core/imagedownloader.h @@ -28,18 +28,23 @@ public: // Schedule a thumbnail for fetching or calculation. // Returns a placehlder thumbnail. The actual thumbnail will be sent // via a signal later. - QImage fetchThumbnail(PictureEntry &entry, int size); + QImage fetchThumbnail(PictureEntry &entry); // If we change dive, clear all unfinished thumbnail creations void clearWorkQueue(); + static int maxThumbnailSize(); + static int defaultThumbnailSize(); + static int thumbnailSize(double zoomLevel); signals: void thumbnailChanged(QString filename, QImage thumbnail); private: Thumbnailer(); - void processItem(QString filename, int size); + void processItem(QString filename); mutable QMutex lock; QThreadPool pool; + QImage failImage; // Shown when image-fetching fails + QImage dummyImage; // Shown before thumbnail is fetched QMap> workingOn; }; diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp index c5453c3a9..89917761c 100644 --- a/qt-models/divepicturemodel.cpp +++ b/qt-models/divepicturemodel.cpp @@ -8,8 +8,6 @@ #include -static const int maxZoom = 3; // Maximum zoom: thrice of standard size - DivePictureModel *DivePictureModel::instance() { static DivePictureModel *self = new DivePictureModel(); @@ -19,7 +17,7 @@ DivePictureModel *DivePictureModel::instance() DivePictureModel::DivePictureModel() : rowDDStart(0), rowDDEnd(0), zoomLevel(0.0), - defaultSize(defaultIconMetrics().sz_pic) + defaultSize(Thumbnailer::defaultThumbnailSize()) { connect(Thumbnailer::instance(), &Thumbnailer::thumbnailChanged, this, &DivePictureModel::updateThumbnail, Qt::QueuedConnection); @@ -47,22 +45,14 @@ void DivePictureModel::setZoomLevel(int level) void DivePictureModel::updateZoom() { - // Calculate size of thumbnails. The standard size is defaultIconMetrics().sz_pic. - // We use exponential scaling so that the central point is the standard - // size and the minimum and maximum extreme points are a third respectively - // three times the standard size. - // Naturally, these three zoom levels are then represented by - // -1.0 (minimum), 0 (standard) and 1.0 (maximum). The actual size is - // calculated as standard_size*3.0^zoomLevel. - size = static_cast(round(defaultSize * pow(maxZoom, zoomLevel))); + size = Thumbnailer::thumbnailSize(zoomLevel); } void DivePictureModel::updateThumbnails() { - int maxSize = defaultSize * maxZoom; updateZoom(); for (PictureEntry &entry: pictures) - entry.image = Thumbnailer::instance()->fetchThumbnail(entry, maxSize); + entry.image = Thumbnailer::instance()->fetchThumbnail(entry); } void DivePictureModel::updateDivePictures() diff --git a/qt-models/divepicturemodel.h b/qt-models/divepicturemodel.h index 0839630bd..e68c00570 100644 --- a/qt-models/divepicturemodel.h +++ b/qt-models/divepicturemodel.h @@ -31,8 +31,8 @@ private: DivePictureModel(); QList pictures; double zoomLevel; // -1.0: minimum, 0.0: standard, 1.0: maximum - int defaultSize; int size; + int defaultSize; void updateThumbnails(); void updateZoom(); };