Cache pixmaps for album art

This commit is contained in:
David Sansome 2011-08-28 22:52:24 +01:00
parent cd44c47f7b
commit 2c954a5d4a
5 changed files with 62 additions and 11 deletions

View File

@ -19,6 +19,9 @@
#include "globalsearch.h"
#include "core/logging.h"
#include <QStringBuilder>
#include <QUrl>
GlobalSearch::GlobalSearch(QObject* parent)
: QObject(parent),
next_id_(1)
@ -30,7 +33,8 @@ void GlobalSearch::AddProvider(SearchProvider* provider) {
SLOT(ResultsAvailableSlot(int,SearchProvider::ResultList)));
connect(provider, SIGNAL(SearchFinished(int)),
SLOT(SearchFinishedSlot(int)));
connect(provider, SIGNAL(ArtLoaded(int,QImage)), SIGNAL(ArtLoaded(int,QImage)));
connect(provider, SIGNAL(ArtLoaded(int,QImage)),
SLOT(ArtLoadedSlot(int,QImage)));
connect(provider, SIGNAL(destroyed(QObject*)),
SLOT(ProviderDestroyedSlot(QObject*)));
@ -48,9 +52,22 @@ int GlobalSearch::SearchAsync(const QString& query) {
return id;
}
void GlobalSearch::ResultsAvailableSlot(int id, const SearchProvider::ResultList& results) {
if (!results.isEmpty())
emit ResultsAvailable(id, results);
QString GlobalSearch::PixmapCacheKey(const SearchProvider::Result& result) const {
return QString::number(qulonglong(result.provider_))
% "," % QString::number(int(result.type_))
% "," % result.metadata_.url().toString();
}
void GlobalSearch::ResultsAvailableSlot(int id, SearchProvider::ResultList results) {
if (results.isEmpty())
return;
// Load cached pixmaps into the results
for (SearchProvider::ResultList::iterator it = results.begin() ; it != results.end() ; ++it) {
it->pixmap_cache_key_ = PixmapCacheKey(*it);
}
emit ResultsAvailable(id, results);
}
void GlobalSearch::SearchFinishedSlot(int id) {
@ -85,7 +102,22 @@ void GlobalSearch::ProviderDestroyedSlot(QObject* object) {
int GlobalSearch::LoadArtAsync(const SearchProvider::Result& result) {
const int id = next_id_ ++;
pending_art_searches_[id] = result.pixmap_cache_key_;
result.provider_->LoadArtAsync(id, result);
return id;
}
void GlobalSearch::ArtLoadedSlot(int id, const QImage& image) {
const QString key = pending_art_searches_.take(id);
QPixmap pixmap = QPixmap::fromImage(image);
pixmap_cache_.insert(key, pixmap);
emit ArtLoaded(id, pixmap);
}
bool GlobalSearch::FindCachedPixmap(const SearchProvider::Result& result,
QPixmap* pixmap) const {
return pixmap_cache_.find(result.pixmap_cache_key_, pixmap);
}

View File

@ -19,6 +19,7 @@
#define GLOBALSEARCH_H
#include <QObject>
#include <QPixmapCache>
#include "searchprovider.h"
@ -34,26 +35,36 @@ public:
int SearchAsync(const QString& query);
int LoadArtAsync(const SearchProvider::Result& result);
bool FindCachedPixmap(const SearchProvider::Result& result, QPixmap* pixmap) const;
signals:
void ResultsAvailable(int id, const SearchProvider::ResultList& results);
void ProviderSearchFinished(int id, const SearchProvider* provider);
void SearchFinished(int id);
void ArtLoaded(int id, const QImage& image);
void ArtLoaded(int id, const QPixmap& pixmap);
void ProviderDestroyed(SearchProvider* provider);
private slots:
void ResultsAvailableSlot(int id, const SearchProvider::ResultList& results);
void ResultsAvailableSlot(int id, SearchProvider::ResultList results);
void SearchFinishedSlot(int id);
void ArtLoadedSlot(int id, const QImage& image);
void ProviderDestroyedSlot(QObject* object);
private:
QString PixmapCacheKey(const SearchProvider::Result& result) const;
private:
QList<SearchProvider*> providers_;
int next_id_;
QMap<int, int> pending_search_providers_;
QPixmapCache pixmap_cache_;
QMap<int, QString> pending_art_searches_;
};
#endif // GLOBALSEARCH_H

View File

@ -67,7 +67,7 @@ GlobalSearchWidget::GlobalSearchWidget(QWidget* parent)
connect(engine_, SIGNAL(ResultsAvailable(int,SearchProvider::ResultList)),
SLOT(AddResults(int,SearchProvider::ResultList)));
connect(engine_, SIGNAL(SearchFinished(int)), SLOT(SearchFinished(int)));
connect(engine_, SIGNAL(ArtLoaded(int,QImage)), SLOT(ArtLoaded(int,QImage)));
connect(engine_, SIGNAL(ArtLoaded(int,QPixmap)), SLOT(ArtLoaded(int,QPixmap)));
}
GlobalSearchWidget::~GlobalSearchWidget() {
@ -164,6 +164,11 @@ void GlobalSearchWidget::AddResults(int id, const SearchProvider::ResultList& re
QStandardItem* item = new QStandardItem;
item->setData(QVariant::fromValue(result), Role_Result);
QPixmap pixmap;
if (engine_->FindCachedPixmap(result, &pixmap)) {
item->setData(pixmap, Qt::DecorationRole);
}
model_->appendRow(item);
}
@ -315,12 +320,11 @@ void GlobalSearchWidget::LazyLoadArt(const QModelIndex& proxy_index) {
art_requests_[id] = source_index;
}
void GlobalSearchWidget::ArtLoaded(int id, const QImage& image) {
void GlobalSearchWidget::ArtLoaded(int id, const QPixmap& pixmap) {
if (!art_requests_.contains(id))
return;
QModelIndex index = art_requests_.take(id);
model_->itemFromIndex(index)->setData(
GlobalSearchItemDelegate::ScaleAndPad(image), Qt::DecorationRole);
model_->itemFromIndex(index)->setData(pixmap, Qt::DecorationRole);
}

View File

@ -64,7 +64,7 @@ private slots:
void SearchFinished(int id);
void AddResults(int id, const SearchProvider::ResultList& results);
void ArtLoaded(int id, const QImage& image);
void ArtLoaded(int id, const QPixmap& pixmap);
private:
void Reset();

View File

@ -42,13 +42,17 @@ public:
Type_Album
};
// This must be set by the provder using the constructor.
SearchProvider* provider_;
// These must be set explicitly by the provider.
Type type_;
Song metadata_;
// How many songs in the album - valid only if type == Type_Album.
int album_size_;
QString pixmap_cache_key_;
};
typedef QList<Result> ResultList;