mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +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(); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
| 	QImage thumbnail = getThumbnailFromCache(filename); | ||||
|  | @ -236,6 +253,17 @@ QImage Thumbnailer::fetchThumbnail(PictureEntry &entry) | |||
| 	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() | ||||
| { | ||||
| 	QMutexLocker l(&lock); | ||||
|  |  | |||
|  | @ -34,6 +34,9 @@ public: | |||
| 	// via a signal later.
 | ||||
| 	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
 | ||||
| 	void clearWorkQueue(); | ||||
| 	static int maxThumbnailSize(); | ||||
|  | @ -46,6 +49,7 @@ signals: | |||
| 	void thumbnailChanged(QString filename, QImage thumbnail); | ||||
| private: | ||||
| 	Thumbnailer(); | ||||
| 	void recalculate(QString filename); | ||||
| 	void processItem(QString filename, bool tryDownload); | ||||
| 
 | ||||
| 	mutable QMutex lock; | ||||
|  |  | |||
|  | @ -54,27 +54,38 @@ void TabDivePhotos::contextMenuEvent(QContextMenuEvent *event) | |||
| 	popup.addSeparator(); | ||||
| 	popup.addAction(tr("Delete selected images"), this, SLOT(removeSelectedPhotos())); | ||||
| 	popup.addAction(tr("Delete all images"), this, SLOT(removeAllPhotos())); | ||||
| 	popup.addAction(tr("Recalculate selected thumbnails"), this, SLOT(recalculateSelectedThumbnails())); | ||||
| 	popup.exec(event->globalPos()); | ||||
| 	event->accept(); | ||||
| } | ||||
| 
 | ||||
| void TabDivePhotos::removeSelectedPhotos() | ||||
| QVector<QString> TabDivePhotos::getSelectedFilenames() const | ||||
| { | ||||
| 	QVector<QString> selectedPhotos; | ||||
| 	if (!ui->photosView->selectionModel()->hasSelection()) | ||||
| 		return; | ||||
| 	QModelIndexList indexes =  ui->photosView->selectionModel()->selectedRows(); | ||||
| 		return selectedPhotos; | ||||
| 	QModelIndexList indexes = ui->photosView->selectionModel()->selectedRows(); | ||||
| 	if (indexes.count() == 0) | ||||
| 		indexes = ui->photosView->selectionModel()->selectedIndexes(); | ||||
| 	QVector<QString> photosToDelete; | ||||
| 	photosToDelete.reserve(indexes.count()); | ||||
| 	selectedPhotos.reserve(indexes.count()); | ||||
| 	for (const auto &photo: indexes) { | ||||
| 		if (photo.isValid()) { | ||||
| 			QString fileUrl = photo.data(Qt::DisplayPropertyRole).toString(); | ||||
| 			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.
 | ||||
|  |  | |||
|  | @ -26,11 +26,13 @@ private slots: | |||
| 	void addPhotosFromURL(); | ||||
| 	void removeAllPhotos(); | ||||
| 	void removeSelectedPhotos(); | ||||
| 	void recalculateSelectedThumbnails(); | ||||
| 	void changeZoomLevel(int delta); | ||||
| 
 | ||||
| private: | ||||
| 	Ui::TabDivePhotos *ui; | ||||
| 	DivePictureModel *divePictureModel; | ||||
| 	QVector<QString> getSelectedFilenames() const; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue