Merge pull request #4382 from TheUbuntuGuy/libcache

Add persistent disk cache for library pixmaps.  Fixes #4379
This commit is contained in:
David Sansome 2014-05-28 14:55:51 +10:00
commit acaa374139
2 changed files with 38 additions and 2 deletions

View File

@ -21,7 +21,10 @@
#include <QFuture>
#include <QFutureWatcher>
#include <QIODevice>
#include <QMetaEnum>
#include <QNetworkCacheMetaData>
#include <QNetworkDiskCache>
#include <QPixmapCache>
#include <QSettings>
#include <QStringList>
@ -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,7 +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<LibraryModel::QueryResult> RootQueryFuture;
typedef QFutureWatcher<LibraryModel::QueryResult> RootQueryWatcher;
@ -84,6 +88,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 +105,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 +463,16 @@ QVariant LibraryModel::AlbumIcon(const QModelIndex& index) {
return cached_pixmap;
}
// Try to load it from the disk cache
std::unique_ptr<QIODevice> cache (icon_cache_->data(QUrl(cache_key)));
if (cache) {
QImage cached_pixmap;
if (cached_pixmap.load(cache.get(), "XPM")) {
QPixmapCache::insert(cache_key, QPixmap::fromImage(cached_pixmap));
return QPixmap::fromImage(cached_pixmap);
}
}
// Maybe we're loading a pixmap already?
if (pending_cache_keys_.contains(cache_key)) {
return no_cover_icon_;
@ -488,6 +507,18 @@ 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))) {
QNetworkCacheMetaData item_metadata;
item_metadata.setSaveToDisk(true);
item_metadata.setUrl(QUrl(cache_key));
QIODevice* cache = icon_cache_->prepare(item_metadata);
if (cache) {
image.save(cache, "XPM");
icon_cache_->insert(cache);
}
}
const QModelIndex index = ItemToIndex(item);
emit dataChanged(index, index);
}

View File

@ -20,6 +20,7 @@
#include <QAbstractItemModel>
#include <QIcon>
#include <QNetworkDiskCache>
#include "libraryitem.h"
#include "libraryquery.h"
@ -47,7 +48,8 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
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<LibraryItem> {
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_;