1 /* This file is part of Clementine. 2 Copyright 2010-2012, David Sansome <me@davidsansome.com> 3 Copyright 2010-2012, 2014, John Maguire <john.maguire@gmail.com> 4 Copyright 2011, Paweł Bara <keirangtp@gmail.com> 5 Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com> 6 7 Clementine is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 Clementine is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Clementine. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef COVERS_ALBUMCOVERLOADER_H_ 22 #define COVERS_ALBUMCOVERLOADER_H_ 23 24 #include "albumcoverloaderoptions.h" 25 #include "config.h" 26 #include "core/song.h" 27 28 #include <QImage> 29 #include <QMutex> 30 #include <QObject> 31 #include <QQueue> 32 #include <QUrl> 33 34 class NetworkAccessManager; 35 class QNetworkReply; 36 37 class AlbumCoverLoader : public QObject { 38 Q_OBJECT 39 40 public: 41 explicit AlbumCoverLoader(QObject* parent = nullptr); 42 Stop()43 void Stop() { stop_requested_ = true; } 44 45 static QString ImageCacheDir(); 46 47 quint64 LoadImageAsync(const AlbumCoverLoaderOptions& options, 48 const Song& song); 49 virtual quint64 LoadImageAsync(const AlbumCoverLoaderOptions& options, 50 const QString& art_automatic, 51 const QString& art_manual, 52 const QString& song_filename = QString(), 53 const QImage& embedded_image = QImage()); 54 55 void CancelTask(quint64 id); 56 void CancelTasks(const QSet<quint64>& ids); 57 58 static QPixmap TryLoadPixmap(const QString& automatic, const QString& manual, 59 const QString& filename = QString()); 60 static QImage ScaleAndPad(const AlbumCoverLoaderOptions& options, 61 const QImage& image); 62 63 signals: 64 void ImageLoaded(quint64 id, const QImage& image); 65 void ImageLoaded(quint64 id, const QImage& scaled, const QImage& original); 66 67 protected slots: 68 void ProcessTasks(); 69 void RemoteFetchFinished(QNetworkReply* reply); 70 #ifdef HAVE_SPOTIFY 71 void SpotifyImageLoaded(const QString& url, const QImage& image); 72 #endif 73 74 protected: 75 enum State { State_TryingManual, State_TryingAuto, }; 76 77 struct Task { TaskTask78 Task() : redirects(0) {} 79 80 AlbumCoverLoaderOptions options; 81 82 quint64 id; 83 QString art_automatic; 84 QString art_manual; 85 QString song_filename; 86 QImage embedded_image; 87 State state; 88 int redirects; 89 }; 90 91 struct TryLoadResult { TryLoadResultTryLoadResult92 TryLoadResult(bool async, bool success, const QImage& i) 93 : started_async(async), loaded_success(success), image(i) {} 94 95 bool started_async; 96 bool loaded_success; 97 QImage image; 98 }; 99 100 void ProcessTask(Task* task); 101 void NextState(Task* task); 102 TryLoadResult TryLoadImage(const Task& task); 103 104 bool stop_requested_; 105 106 QMutex mutex_; 107 QQueue<Task> tasks_; 108 QMap<QNetworkReply*, Task> remote_tasks_; 109 QMap<QString, Task> remote_spotify_tasks_; 110 quint64 next_id_; 111 112 NetworkAccessManager* network_; 113 114 bool connected_spotify_; 115 116 static const int kMaxRedirects = 3; 117 }; 118 119 #endif // COVERS_ALBUMCOVERLOADER_H_ 120