mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 22:03:23 +00:00
Dive pictures: give user option to recalculate thumbnails
Even though hashes of image contents are calculated, the hashes are not compared to actual file contents in routine-operation. Therefore give the user the option to recalculate thumbnails, should they have edited the picture. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
f265504dab
commit
23d38a982d
4 changed files with 52 additions and 7 deletions
|
@ -184,6 +184,23 @@ static void addThumbnailToCache(const QImage &thumbnail, const QString &picture_
|
||||||
file.commit();
|
file.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thumbnailer::recalculate(QString filename)
|
||||||
|
{
|
||||||
|
auto res = getHashedImage(filename, true);
|
||||||
|
|
||||||
|
// If we couldn't load the image from disk -> leave old thumbnail.
|
||||||
|
// The case "load from web" is a bit inconsistent: it will call into processItem() later
|
||||||
|
// and therefore a "broken" image symbol may be shown.
|
||||||
|
if (res.second || res.first.isNull())
|
||||||
|
return;
|
||||||
|
QImage thumbnail = res.first;
|
||||||
|
addThumbnailToCache(thumbnail, filename);
|
||||||
|
|
||||||
|
QMutexLocker l(&lock);
|
||||||
|
emit thumbnailChanged(filename, thumbnail);
|
||||||
|
workingOn.remove(filename);
|
||||||
|
}
|
||||||
|
|
||||||
void Thumbnailer::processItem(QString filename, bool tryDownload)
|
void Thumbnailer::processItem(QString filename, bool tryDownload)
|
||||||
{
|
{
|
||||||
QImage thumbnail = getThumbnailFromCache(filename);
|
QImage thumbnail = getThumbnailFromCache(filename);
|
||||||
|
@ -236,6 +253,17 @@ QImage Thumbnailer::fetchThumbnail(PictureEntry &entry)
|
||||||
return dummyImage;
|
return dummyImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thumbnailer::calculateThumbnails(const QVector<QString> &filenames)
|
||||||
|
{
|
||||||
|
QMutexLocker l(&lock);
|
||||||
|
for (const QString &filename: filenames) {
|
||||||
|
if (!workingOn.contains(filename)) {
|
||||||
|
workingOn.insert(filename,
|
||||||
|
QtConcurrent::run(&pool, [this, filename]() { recalculate(filename); }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Thumbnailer::clearWorkQueue()
|
void Thumbnailer::clearWorkQueue()
|
||||||
{
|
{
|
||||||
QMutexLocker l(&lock);
|
QMutexLocker l(&lock);
|
||||||
|
|
|
@ -34,6 +34,9 @@ public:
|
||||||
// via a signal later.
|
// via a signal later.
|
||||||
QImage fetchThumbnail(PictureEntry &entry);
|
QImage fetchThumbnail(PictureEntry &entry);
|
||||||
|
|
||||||
|
// Schedule multiple thumbnails for forced recalculation
|
||||||
|
void calculateThumbnails(const QVector<QString> &filenames);
|
||||||
|
|
||||||
// If we change dive, clear all unfinished thumbnail creations
|
// If we change dive, clear all unfinished thumbnail creations
|
||||||
void clearWorkQueue();
|
void clearWorkQueue();
|
||||||
static int maxThumbnailSize();
|
static int maxThumbnailSize();
|
||||||
|
@ -46,6 +49,7 @@ signals:
|
||||||
void thumbnailChanged(QString filename, QImage thumbnail);
|
void thumbnailChanged(QString filename, QImage thumbnail);
|
||||||
private:
|
private:
|
||||||
Thumbnailer();
|
Thumbnailer();
|
||||||
|
void recalculate(QString filename);
|
||||||
void processItem(QString filename, bool tryDownload);
|
void processItem(QString filename, bool tryDownload);
|
||||||
|
|
||||||
mutable QMutex lock;
|
mutable QMutex lock;
|
||||||
|
|
|
@ -54,27 +54,38 @@ void TabDivePhotos::contextMenuEvent(QContextMenuEvent *event)
|
||||||
popup.addSeparator();
|
popup.addSeparator();
|
||||||
popup.addAction(tr("Delete selected images"), this, SLOT(removeSelectedPhotos()));
|
popup.addAction(tr("Delete selected images"), this, SLOT(removeSelectedPhotos()));
|
||||||
popup.addAction(tr("Delete all images"), this, SLOT(removeAllPhotos()));
|
popup.addAction(tr("Delete all images"), this, SLOT(removeAllPhotos()));
|
||||||
|
popup.addAction(tr("Recalculate selected thumbnails"), this, SLOT(recalculateSelectedThumbnails()));
|
||||||
popup.exec(event->globalPos());
|
popup.exec(event->globalPos());
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabDivePhotos::removeSelectedPhotos()
|
QVector<QString> TabDivePhotos::getSelectedFilenames() const
|
||||||
{
|
{
|
||||||
|
QVector<QString> selectedPhotos;
|
||||||
if (!ui->photosView->selectionModel()->hasSelection())
|
if (!ui->photosView->selectionModel()->hasSelection())
|
||||||
return;
|
return selectedPhotos;
|
||||||
QModelIndexList indexes = ui->photosView->selectionModel()->selectedRows();
|
QModelIndexList indexes = ui->photosView->selectionModel()->selectedRows();
|
||||||
if (indexes.count() == 0)
|
if (indexes.count() == 0)
|
||||||
indexes = ui->photosView->selectionModel()->selectedIndexes();
|
indexes = ui->photosView->selectionModel()->selectedIndexes();
|
||||||
QVector<QString> photosToDelete;
|
selectedPhotos.reserve(indexes.count());
|
||||||
photosToDelete.reserve(indexes.count());
|
|
||||||
for (const auto &photo: indexes) {
|
for (const auto &photo: indexes) {
|
||||||
if (photo.isValid()) {
|
if (photo.isValid()) {
|
||||||
QString fileUrl = photo.data(Qt::DisplayPropertyRole).toString();
|
QString fileUrl = photo.data(Qt::DisplayPropertyRole).toString();
|
||||||
if (!fileUrl.isEmpty())
|
if (!fileUrl.isEmpty())
|
||||||
photosToDelete.push_back(fileUrl);
|
selectedPhotos.push_back(fileUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DivePictureModel::instance()->removePictures(photosToDelete);
|
return selectedPhotos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDivePhotos::removeSelectedPhotos()
|
||||||
|
{
|
||||||
|
DivePictureModel::instance()->removePictures(getSelectedFilenames());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDivePhotos::recalculateSelectedThumbnails()
|
||||||
|
{
|
||||||
|
Thumbnailer::instance()->calculateThumbnails(getSelectedFilenames());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: This looks overly wrong. We shouldn't call MainWindow to retrieve the DiveList to add Images.
|
//TODO: This looks overly wrong. We shouldn't call MainWindow to retrieve the DiveList to add Images.
|
||||||
|
|
|
@ -26,11 +26,13 @@ private slots:
|
||||||
void addPhotosFromURL();
|
void addPhotosFromURL();
|
||||||
void removeAllPhotos();
|
void removeAllPhotos();
|
||||||
void removeSelectedPhotos();
|
void removeSelectedPhotos();
|
||||||
|
void recalculateSelectedThumbnails();
|
||||||
void changeZoomLevel(int delta);
|
void changeZoomLevel(int delta);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::TabDivePhotos *ui;
|
Ui::TabDivePhotos *ui;
|
||||||
DivePictureModel *divePictureModel;
|
DivePictureModel *divePictureModel;
|
||||||
|
QVector<QString> getSelectedFilenames() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue