diff options
-rw-r--r-- | core/imagedownloader.cpp | 17 | ||||
-rw-r--r-- | core/imagedownloader.h | 10 | ||||
-rw-r--r-- | desktop-widgets/divelogexportdialog.cpp | 2 | ||||
-rw-r--r-- | profile-widget/profilewidget2.cpp | 19 | ||||
-rw-r--r-- | profile-widget/profilewidget2.h | 5 | ||||
-rw-r--r-- | qt-models/divepicturemodel.cpp | 2 |
6 files changed, 40 insertions, 15 deletions
diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp index d78409a3c..1559b129b 100644 --- a/core/imagedownloader.cpp +++ b/core/imagedownloader.cpp @@ -456,8 +456,23 @@ void Thumbnailer::imageDownloadFailed(QString filename) workingOn.remove(filename); } -QImage Thumbnailer::fetchThumbnail(const QString &filename) +QImage Thumbnailer::fetchThumbnail(const QString &filename, bool synchronous) { + if (synchronous) { + // In synchronous mode, first try the thumbnail cache. + Thumbnail thumbnail = getThumbnailFromCache(filename); + if (!thumbnail.img.isNull()) + return thumbnail.img; + + // If that didn't work, try to thumbnail the image. + thumbnail = getHashedImage(filename, false); + if (thumbnail.type == MEDIATYPE_STILL_LOADING || thumbnail.img.isNull()) + return failImage; // No support for delayed thumbnails (web). + + int size = maxThumbnailSize(); + return thumbnail.img.scaled(size, size, Qt::KeepAspectRatio); + } + QMutexLocker l(&lock); // We are not currently fetching this thumbnail - add it to the list. diff --git a/core/imagedownloader.h b/core/imagedownloader.h index e0d70f59f..280383250 100644 --- a/core/imagedownloader.h +++ b/core/imagedownloader.h @@ -31,9 +31,13 @@ public: static Thumbnailer *instance(); // Schedule a thumbnail for fetching or calculation. - // Returns a placeholder thumbnail. The actual thumbnail will be sent - // via a signal later. - QImage fetchThumbnail(const QString &filename); + // If synchronous is false, returns a placeholder thumbnail. + // The actual thumbnail will be sent via a signal later. + // If synchronous is true, try to fetch the actual thumbnail. + // In this mode only precalculated thumbnails or thumbnails + // from pictures are returned. Video extraction and remote + // images are not supported. + QImage fetchThumbnail(const QString &filename, bool synchronous); // Schedule multiple thumbnails for forced recalculation void calculateThumbnails(const QVector<QString> &filenames); diff --git a/desktop-widgets/divelogexportdialog.cpp b/desktop-widgets/divelogexportdialog.cpp index 37fb8cee4..04f0b03de 100644 --- a/desktop-widgets/divelogexportdialog.cpp +++ b/desktop-widgets/divelogexportdialog.cpp @@ -254,7 +254,7 @@ void DiveLogExportDialog::exportProfile(const QString filename, const bool selec void DiveLogExportDialog::saveProfile(const struct dive *dive, const QString filename) { ProfileWidget2 *profile = MainWindow::instance()->graphics; - profile->plotDive(dive, true); + profile->plotDive(dive, true, false, true); profile->setToolTipVisibile(false); QPixmap pix = profile->grab(); profile->setToolTipVisibile(true); diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 3a9fd0c5f..85109875f 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -165,7 +165,7 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent), addActionShortcut(Qt::Key_Right, &ProfileWidget2::keyRightAction); connect(Thumbnailer::instance(), &Thumbnailer::thumbnailChanged, this, &ProfileWidget2::updateThumbnail, Qt::QueuedConnection); - connect(DivePictureModel::instance(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(plotPictures())); + connect(DivePictureModel::instance(), &DivePictureModel::rowsInserted, this, &ProfileWidget2::plotPictures); connect(DivePictureModel::instance(), &DivePictureModel::picturesRemoved, this, &ProfileWidget2::removePictures); connect(DivePictureModel::instance(), &DivePictureModel::modelReset, this, &ProfileWidget2::plotPictures); #endif // SUBSURFACE_MOBILE @@ -548,7 +548,7 @@ void ProfileWidget2::resetZoom() } // Currently just one dive, but the plan is to enable All of the selected dives. -void ProfileWidget2::plotDive(const struct dive *d, bool force, bool doClearPictures) +void ProfileWidget2::plotDive(const struct dive *d, bool force, bool doClearPictures, bool plotPicturesSynchronously) { static bool firstCall = true; #ifndef SUBSURFACE_MOBILE @@ -827,7 +827,7 @@ void ProfileWidget2::plotDive(const struct dive *d, bool force, bool doClearPict if (doClearPictures) clearPictures(); else - plotPictures(); + plotPicturesInternal(plotPicturesSynchronously); toolTipItem->refresh(mapToScene(mapFromGlobal(QCursor::pos()))); #endif @@ -2153,7 +2153,7 @@ void ProfileWidget2::updateThumbnail(QString filename, QImage thumbnail, duratio } // Create a PictureEntry object and add its thumbnail to the scene if profile pictures are shown. -ProfileWidget2::PictureEntry::PictureEntry(offset_t offsetIn, const QString &filenameIn, QGraphicsScene *scene) : offset(offsetIn), +ProfileWidget2::PictureEntry::PictureEntry(offset_t offsetIn, const QString &filenameIn, QGraphicsScene *scene, bool synchronous) : offset(offsetIn), duration(duration_t {0}), filename(filenameIn), thumbnail(new DivePictureItem) @@ -2161,7 +2161,7 @@ ProfileWidget2::PictureEntry::PictureEntry(offset_t offsetIn, const QString &fil int size = Thumbnailer::defaultThumbnailSize(); scene->addItem(thumbnail.get()); thumbnail->setVisible(prefs.show_pictures_in_profile); - QImage img = Thumbnailer::instance()->fetchThumbnail(filename).scaled(size, size, Qt::KeepAspectRatio); + QImage img = Thumbnailer::instance()->fetchThumbnail(filename, synchronous).scaled(size, size, Qt::KeepAspectRatio); thumbnail->setPixmap(QPixmap::fromImage(img)); thumbnail->setFileUrl(filename); } @@ -2228,6 +2228,11 @@ void ProfileWidget2::updateThumbnailXPos(PictureEntry &e) // This function resets the picture thumbnails of the current dive. void ProfileWidget2::plotPictures() { + plotPicturesInternal(false); +} + +void ProfileWidget2::plotPicturesInternal(bool synchronous) +{ pictures.clear(); if (currentState == ADD || currentState == PLAN) return; @@ -2238,7 +2243,7 @@ void ProfileWidget2::plotPictures() // Note that FOR_EACH_PICTURE handles current_dive being null gracefully. FOR_EACH_PICTURE(current_dive) { if (picture->offset.seconds > 0 && picture->offset.seconds <= current_dive->duration.seconds) - pictures.emplace_back(picture->offset, QString(picture->filename), scene()); + pictures.emplace_back(picture->offset, QString(picture->filename), scene(), synchronous); } if (pictures.empty()) return; @@ -2346,7 +2351,7 @@ void ProfileWidget2::dropEvent(QDropEvent *event) // The parameters are passed directly to the contructor. // The call returns an iterator to the new element (which might differ from // the old iterator, since the buffer might have been reallocated). - newPos = pictures.emplace(newPos, offset, filename, scene()); + newPos = pictures.emplace(newPos, offset, filename, scene(), false); updateThumbnailXPos(*newPos); calculatePictureYPositions(); } diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h index 679abcf1d..300e46e39 100644 --- a/profile-widget/profilewidget2.h +++ b/profile-widget/profilewidget2.h @@ -75,7 +75,7 @@ public: ProfileWidget2(QWidget *parent = 0); void resetZoom(); void scale(qreal sx, qreal sy); - void plotDive(const struct dive *d = 0, bool force = false, bool clearPictures = false); + void plotDive(const struct dive *d = 0, bool force = false, bool clearPictures = false, bool plotPicturesSynchronously = false); void setupItem(AbstractProfilePolygonItem *item, DiveCartesianAxis *vAxis, int vData, int hData, int zValue); void setPrintMode(bool mode, bool grayscale = false); bool getPrintMode(); @@ -173,6 +173,7 @@ private: /*methods*/ void createPPGas(PartialPressureGasItem *item, int verticalColumn, color_index_t color, color_index_t colorAlert, const double *thresholdSettingsMin, const double *thresholdSettingsMax); void clearPictures(); + void plotPicturesInternal(bool synchronous); private: DivePlotDataModel *dataModel; int zoomLevel; @@ -240,7 +241,7 @@ private: std::unique_ptr<DivePictureItem> thumbnail; // For videos with known duration, we represent the duration of the video by a line std::unique_ptr<QGraphicsRectItem> durationLine; - PictureEntry (offset_t offsetIn, const QString &filenameIn, QGraphicsScene *scene); + PictureEntry (offset_t offsetIn, const QString &filenameIn, QGraphicsScene *scene, bool synchronous); bool operator< (const PictureEntry &e) const; }; void updateThumbnailXPos(PictureEntry &e); diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp index 4db81d546..babd404f5 100644 --- a/qt-models/divepicturemodel.cpp +++ b/qt-models/divepicturemodel.cpp @@ -42,7 +42,7 @@ void DivePictureModel::updateThumbnails() { updateZoom(); for (PictureEntry &entry: pictures) - entry.image = Thumbnailer::instance()->fetchThumbnail(entry.filename); + entry.image = Thumbnailer::instance()->fetchThumbnail(entry.filename, false); } void DivePictureModel::updateDivePictures() |