aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/imagedownloader.cpp76
1 files changed, 44 insertions, 32 deletions
diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp
index e5dfc21d7..2cf5e5d33 100644
--- a/core/imagedownloader.cpp
+++ b/core/imagedownloader.cpp
@@ -65,45 +65,57 @@ void ImageDownloader::saveImage(QNetworkReply *reply)
reply->deleteLater();
}
-static void loadPicture(QUrl url, QString filename)
+// Fetch a picture from the given filename. If this is a non-remote filename, fetch it from disk.
+// Remote files are fetched from the net in a background thread. In such a case, the output-flag
+// "stillLoading" is set to true.
+// If the input-flag "tryDownload" is set to false, no download attempt is made. This is to
+// prevent infinite loops, where failed image downloads would be repeated ad infinitum.
+// Returns: fetched image, stillLoading flag
+static std::pair<QImage, bool> fetchImage(const QString &filename, const QString &originalFilename, bool tryDownload)
{
- // This has to be done in UI main thread, because QNetworkManager refuses
- // to treat requests from other threads.
- QMetaObject::invokeMethod(ImageDownloader::instance(), "load", Qt::AutoConnection, Q_ARG(QUrl, url), Q_ARG(QString, filename));
-}
-
-// Returns: thumbnail, still loading
-static std::pair<QImage,bool> getHashedImage(const QString &file_in, bool tryDownload)
-{
- QString file = file_in.startsWith("file://", Qt::CaseInsensitive) ? file_in.mid(7) : file_in;
QImage thumb;
bool stillLoading = false;
- QUrl url = QUrl::fromUserInput(localFilePath(file));
- if (url.isLocalFile())
+ QUrl url = QUrl::fromUserInput(filename);
+ if (url.isLocalFile()) {
thumb.load(url.toLocalFile());
- if (!thumb.isNull()) {
- // We loaded successfully. Now, make sure hash is up to date.
- hashPicture(file);
+ // If we loaded successfully, make sure the hash is up to date.
+ // Note that hashPicture() takes the *original* filename.
+ if (!thumb.isNull())
+ hashPicture(originalFilename);
} else if (tryDownload) {
- // This did not load anything. Let's try to get the image from other sources
- QString filenameLocal = localFilePath(file);
- // Load locally from translated file name if it is different
- if (filenameLocal != file)
- thumb.load(filenameLocal);
- if (!thumb.isNull()) {
- // Make sure the hash still matches the image file
- hashPicture(filenameLocal);
- } else {
- // Interpret filename as URL
- QUrl url = QUrl::fromUserInput(filenameLocal);
- if (!url.isLocalFile() && url.isValid()) {
- loadPicture(url, file);
- stillLoading = true;
- }
- }
+ // This has to be done in UI main thread, because QNetworkManager refuses
+ // to treat requests from other threads. invokeMethod() is Qt's way of calling a
+ // function in a different thread, namely the thread the called object is associated to.
+ QMetaObject::invokeMethod(ImageDownloader::instance(), "load", Qt::AutoConnection, Q_ARG(QUrl, url), Q_ARG(QString, originalFilename));
+ stillLoading = true;
}
+ return { thumb, stillLoading };
+}
+
+// Fetch a picture based on its original filename. If there is a translated filename (obtained either
+// by the find-moved-picture functionality or the filename of the local cache of a remote picture),
+// try that first. If fetching from the translated filename fails, this could mean that the image
+// was downloaded previously, but for some reason the cached picture was lost. Therefore, in such a
+// case, try the canonical filename. If that likewise fails, give up. For input and output parameters
+// see fetchImage() above.
+static std::pair<QImage, bool> getHashedImage(const QString &filename, bool tryDownload)
+{
+ QImage thumb;
+ bool stillLoading = false;
+ QString localFilename = localFilePath(filename);
+
+ // If there is a translated filename, try that first
+ if (localFilename != filename)
+ std::tie(thumb, stillLoading) = fetchImage(localFilename, filename, tryDownload);
+
+ // Note that the translated filename should never be a remote file and therefore checking for
+ // stillLoading is currently not necessary. But in the future, we might support such a use case
+ // (e.g. images stored in the cloud).
+ if (thumb.isNull() && !stillLoading)
+ std::tie(thumb, stillLoading) = fetchImage(filename, filename, tryDownload);
+
if (thumb.isNull() && !stillLoading)
- qInfo() << "Error loading image" << file << "[local:" << localFilePath(file) << "]";
+ qInfo() << "Error loading image" << filename << "[local:" << localFilename << "]";
return { thumb, stillLoading };
}