diff --git a/src/library/librarymodel.cpp b/src/library/librarymodel.cpp index 3e048da67..3bfa9750c 100644 --- a/src/library/librarymodel.cpp +++ b/src/library/librarymodel.cpp @@ -21,7 +21,10 @@ #include #include +#include #include +#include +#include #include #include #include @@ -37,6 +40,7 @@ #include "core/database.h" #include "core/logging.h" #include "core/taskmanager.h" +#include "core/utilities.h" #include "covers/albumcoverloader.h" #include "playlist/songmimedata.h" #include "smartplaylists/generator.h" @@ -58,6 +62,7 @@ const char* LibraryModel::kSmartPlaylistsSettingsGroup = "SerialisedSmartPlaylists"; const int LibraryModel::kSmartPlaylistsVersion = 4; const int LibraryModel::kPrettyCoverSize = 32; +const qint64 LibraryModel::kIconCacheSize = 100000000; //~100MB typedef QFuture RootQueryFuture; typedef QFutureWatcher RootQueryWatcher; @@ -84,6 +89,7 @@ LibraryModel::LibraryModel(LibraryBackend* backend, Application* app, album_icon_(":/icons/22x22/x-clementine-album.png"), playlists_dir_icon_(IconLoader::Load("folder-sound")), playlist_icon_(":/icons/22x22/x-clementine-albums.png"), + icon_cache_(new QNetworkDiskCache(this)), init_task_id_(-1), use_pretty_covers_(false), show_dividers_(true) { @@ -100,6 +106,10 @@ LibraryModel::LibraryModel(LibraryBackend* backend, Application* app, connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QImage)), SLOT(AlbumArtLoaded(quint64, QImage))); + icon_cache_->setCacheDirectory( + Utilities::GetConfigPath(Utilities::Path_CacheRoot) + "/pixmapcache"); + icon_cache_->setMaximumCacheSize(LibraryModel::kIconCacheSize); + no_cover_icon_ = QPixmap(":nocover.png") .scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); @@ -454,6 +464,20 @@ QVariant LibraryModel::AlbumIcon(const QModelIndex& index) { return cached_pixmap; } + // Try to load it from the disk cache + QIODevice* cache; + cache = icon_cache_->data(QUrl(cache_key)); + if (cache != 0) { + QImage cached_pixmap; + if (cached_pixmap.load(cache, "XPM")) { + delete cache; + qLog(Debug) << "Loading pixmap from disk..."; + QPixmapCache::insert(cache_key, QPixmap::fromImage(cached_pixmap)); + return QPixmap::fromImage(cached_pixmap); + } + delete cache; + } + // Maybe we're loading a pixmap already? if (pending_cache_keys_.contains(cache_key)) { return no_cover_icon_; @@ -488,6 +512,20 @@ void LibraryModel::AlbumArtLoaded(quint64 id, const QImage& image) { QPixmapCache::insert(cache_key, QPixmap::fromImage(image)); } + // if not already in the disk cache + if (icon_cache_->data(QUrl(cache_key)) == 0) { + qLog(Debug) << "Caching new pixmap..."; + QNetworkCacheMetaData* item_metadata = new QNetworkCacheMetaData(); + item_metadata->setSaveToDisk(true); + item_metadata->setUrl(QUrl(cache_key)); + QIODevice* cache = icon_cache_->prepare(*item_metadata); + if (cache != 0) { + image.save(cache, "XPM"); + icon_cache_->insert(cache); + } + delete item_metadata; + } + const QModelIndex index = ItemToIndex(item); emit dataChanged(index, index); } diff --git a/src/library/librarymodel.h b/src/library/librarymodel.h index 302f8ace7..3b7a5cef6 100644 --- a/src/library/librarymodel.h +++ b/src/library/librarymodel.h @@ -20,6 +20,7 @@ #include #include +#include #include "libraryitem.h" #include "libraryquery.h" @@ -47,7 +48,8 @@ class LibraryModel : public SimpleTreeModel { Q_ENUMS(GroupBy); public: - LibraryModel(LibraryBackend* backend, Application* app, QObject* parent = nullptr); + LibraryModel(LibraryBackend* backend, Application* app, + QObject* parent = nullptr); ~LibraryModel(); static const char* kSmartPlaylistsMimeType; @@ -55,6 +57,7 @@ class LibraryModel : public SimpleTreeModel { static const char* kSmartPlaylistsArray; static const int kSmartPlaylistsVersion; static const int kPrettyCoverSize; + static const qint64 kIconCacheSize; enum Role { Role_Type = Qt::UserRole + 1, @@ -279,6 +282,8 @@ signals: QIcon playlists_dir_icon_; QIcon playlist_icon_; + QNetworkDiskCache* icon_cache_; + int init_task_id_; bool use_pretty_covers_;