Merge pull request #4382 from TheUbuntuGuy/libcache
Add persistent disk cache for library pixmaps. Fixes #4379
This commit is contained in:
commit
acaa374139
@ -21,7 +21,10 @@
|
|||||||
|
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
|
#include <QIODevice>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
#include <QNetworkCacheMetaData>
|
||||||
|
#include <QNetworkDiskCache>
|
||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
@ -37,6 +40,7 @@
|
|||||||
#include "core/database.h"
|
#include "core/database.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/taskmanager.h"
|
#include "core/taskmanager.h"
|
||||||
|
#include "core/utilities.h"
|
||||||
#include "covers/albumcoverloader.h"
|
#include "covers/albumcoverloader.h"
|
||||||
#include "playlist/songmimedata.h"
|
#include "playlist/songmimedata.h"
|
||||||
#include "smartplaylists/generator.h"
|
#include "smartplaylists/generator.h"
|
||||||
@ -58,7 +62,7 @@ const char* LibraryModel::kSmartPlaylistsSettingsGroup =
|
|||||||
"SerialisedSmartPlaylists";
|
"SerialisedSmartPlaylists";
|
||||||
const int LibraryModel::kSmartPlaylistsVersion = 4;
|
const int LibraryModel::kSmartPlaylistsVersion = 4;
|
||||||
const int LibraryModel::kPrettyCoverSize = 32;
|
const int LibraryModel::kPrettyCoverSize = 32;
|
||||||
|
const qint64 LibraryModel::kIconCacheSize = 100000000; //~100MB
|
||||||
typedef QFuture<LibraryModel::QueryResult> RootQueryFuture;
|
typedef QFuture<LibraryModel::QueryResult> RootQueryFuture;
|
||||||
typedef QFutureWatcher<LibraryModel::QueryResult> RootQueryWatcher;
|
typedef QFutureWatcher<LibraryModel::QueryResult> RootQueryWatcher;
|
||||||
|
|
||||||
@ -84,6 +88,7 @@ LibraryModel::LibraryModel(LibraryBackend* backend, Application* app,
|
|||||||
album_icon_(":/icons/22x22/x-clementine-album.png"),
|
album_icon_(":/icons/22x22/x-clementine-album.png"),
|
||||||
playlists_dir_icon_(IconLoader::Load("folder-sound")),
|
playlists_dir_icon_(IconLoader::Load("folder-sound")),
|
||||||
playlist_icon_(":/icons/22x22/x-clementine-albums.png"),
|
playlist_icon_(":/icons/22x22/x-clementine-albums.png"),
|
||||||
|
icon_cache_(new QNetworkDiskCache(this)),
|
||||||
init_task_id_(-1),
|
init_task_id_(-1),
|
||||||
use_pretty_covers_(false),
|
use_pretty_covers_(false),
|
||||||
show_dividers_(true) {
|
show_dividers_(true) {
|
||||||
@ -100,6 +105,10 @@ LibraryModel::LibraryModel(LibraryBackend* backend, Application* app,
|
|||||||
connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QImage)),
|
connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QImage)),
|
||||||
SLOT(AlbumArtLoaded(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")
|
no_cover_icon_ = QPixmap(":nocover.png")
|
||||||
.scaled(kPrettyCoverSize, kPrettyCoverSize,
|
.scaled(kPrettyCoverSize, kPrettyCoverSize,
|
||||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
@ -454,6 +463,16 @@ QVariant LibraryModel::AlbumIcon(const QModelIndex& index) {
|
|||||||
return cached_pixmap;
|
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?
|
// Maybe we're loading a pixmap already?
|
||||||
if (pending_cache_keys_.contains(cache_key)) {
|
if (pending_cache_keys_.contains(cache_key)) {
|
||||||
return no_cover_icon_;
|
return no_cover_icon_;
|
||||||
@ -488,6 +507,18 @@ void LibraryModel::AlbumArtLoaded(quint64 id, const QImage& image) {
|
|||||||
QPixmapCache::insert(cache_key, QPixmap::fromImage(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);
|
const QModelIndex index = ItemToIndex(item);
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QNetworkDiskCache>
|
||||||
|
|
||||||
#include "libraryitem.h"
|
#include "libraryitem.h"
|
||||||
#include "libraryquery.h"
|
#include "libraryquery.h"
|
||||||
@ -47,7 +48,8 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
|||||||
Q_ENUMS(GroupBy);
|
Q_ENUMS(GroupBy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LibraryModel(LibraryBackend* backend, Application* app, QObject* parent = nullptr);
|
LibraryModel(LibraryBackend* backend, Application* app,
|
||||||
|
QObject* parent = nullptr);
|
||||||
~LibraryModel();
|
~LibraryModel();
|
||||||
|
|
||||||
static const char* kSmartPlaylistsMimeType;
|
static const char* kSmartPlaylistsMimeType;
|
||||||
@ -55,6 +57,7 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
|||||||
static const char* kSmartPlaylistsArray;
|
static const char* kSmartPlaylistsArray;
|
||||||
static const int kSmartPlaylistsVersion;
|
static const int kSmartPlaylistsVersion;
|
||||||
static const int kPrettyCoverSize;
|
static const int kPrettyCoverSize;
|
||||||
|
static const qint64 kIconCacheSize;
|
||||||
|
|
||||||
enum Role {
|
enum Role {
|
||||||
Role_Type = Qt::UserRole + 1,
|
Role_Type = Qt::UserRole + 1,
|
||||||
@ -279,6 +282,8 @@ signals:
|
|||||||
QIcon playlists_dir_icon_;
|
QIcon playlists_dir_icon_;
|
||||||
QIcon playlist_icon_;
|
QIcon playlist_icon_;
|
||||||
|
|
||||||
|
QNetworkDiskCache* icon_cache_;
|
||||||
|
|
||||||
int init_task_id_;
|
int init_task_id_;
|
||||||
|
|
||||||
bool use_pretty_covers_;
|
bool use_pretty_covers_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user