thumbnailcache.cpp Example File
mediabrowser/thumbnailcache.cpp
#include "thumbnailcache.h"
#include "thumbnailmodel.h"
#include <QtCore/qcryptographichash.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qdir.h>
#include <QtCore/qurl.h>
#include <QtGui/qimagereader.h>
#include <QtGui/qpixmap.h>
#if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0))
uint qHash(const QUrl &url) { return qHash(url.toString()); }
#endif
class Thumbnail
{
public:
Thumbnail(const QUrl &url)
: url(url)
{
}
const QUrl url;
QPixmap pixmap;
private:
ThumbnailCache *cache;
};
class ThumbnailEvent : public QEvent
{
public:
ThumbnailEvent(const QUrl &url, const QImage &image)
: QEvent(QEvent::User)
, url(url)
, image(image)
{
}
const QUrl url;
const QImage image;
};
ThumbnailCache::ThumbnailCache(QObject *parent)
: QThread(parent)
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
, cache(25)
#else
, cache(150)
#endif
, cancelled(false)
{
start(QThread::LowestPriority);
}
ThumbnailCache::~ThumbnailCache()
{
{
QMutexLocker locker(&mutex);
cancelled = true;
waitCondition.wakeOne();
}
wait();
}
QPixmap ThumbnailCache::thumbnail(const QUrl &url)
{
QMutexLocker locker(&mutex);
if (Thumbnail *thumbnail = cache.object(url)) {
return thumbnail->pixmap;
} else {
pendingUrls.enqueue(url);
cache.insert(url, new Thumbnail(url));
waitCondition.wakeOne();
return QPixmap();
}
}
bool ThumbnailCache::event(QEvent *event)
{
if (event->type() == QEvent::User) {
ThumbnailEvent *thumbnailEvent = static_cast<ThumbnailEvent *>(event);
QMutexLocker locker(&mutex);
if (Thumbnail *thumbnail = cache.object(thumbnailEvent->url)) {
thumbnail->pixmap = QPixmap::fromImage(thumbnailEvent->image);
locker.unlock();
emit thumbnailReady();
}
return true;
} else {
return QThread::event(event);
}
}
void ThumbnailCache::run()
{
QMutexLocker locker(&mutex);
while(!cancelled) {
if (!pendingUrls.isEmpty()) {
const QUrl url = pendingUrls.dequeue();
if (cache.contains(url)) {
locker.unlock();
QImage image = loadImage(url);
locker.relock();
if (!image.isNull())
QCoreApplication::postEvent(this, new ThumbnailEvent(url, image));
}
} else {
waitCondition.wait(&mutex);
}
}
}
QImage ThumbnailCache::loadImage(const QUrl &url) const
{
const QString fileName = thumbnailPath(url);
QImageReader reader(fileName);
reader.setQuality(25);
if (reader.supportsOption(QImageIOHandler::Size)) {
QSize size = reader.size();
if (!reader.supportsOption(QImageIOHandler::ScaledSize)
&& (size.width() > 1280 || size.height() > 1280)) {
return QImage();
}
if (size.width() > ThumbnailModel::thumbnailSize.width()
|| size.height() > ThumbnailModel::thumbnailSize.height()) {
size.scale(ThumbnailModel::thumbnailSize, Qt::KeepAspectRatio);
}
reader.setScaledSize(size);
} else {
reader.setScaledSize(ThumbnailModel::thumbnailSize);
}
return reader.read();
}
QString ThumbnailCache::thumbnailPath(const QUrl &url) const
{
#if defined(Q_OS_UNIX) && !(defined(Q_OS_SYMBIAN) || defined(Q_OS_MAC))
#if defined(Q_WS_MAEMO_5)
QString thumbnailPath = QDir::homePath()
+ QLatin1String("/.thumbnails/cropped/")
+ QCryptographicHash::hash(url.toString().toUtf8(), QCryptographicHash::Md5).toHex()
+ QLatin1String(".jpeg");
#elif defined(Q_WS_MAEMO_6)
QString thumbnailPath = QDir::homePath()
+ QLatin1String("/.thumbnails/grid/")
+ QCryptographicHash::hash(url.toString().toUtf8(), QCryptographicHash::Md5).toHex()
+ QLatin1String(".jpeg");
#else
QString thumbnailPath = QDir::homePath()
+ QLatin1String("/.thumbnails/normal/")
+ QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Md5).toHex()
+ QLatin1String(".png");
#endif
if (QFile::exists(thumbnailPath))
return thumbnailPath;
#endif
return url.toLocalFile();
}
[+] Documentation Feedback