#include "pixmaploader.h" #include "settings.h" #include #include "settings.h" // PixmapLoaderThread PixmapLoaderThread::PixmapLoaderThread(PixmapLoader *loader) : QThread(loader) , m_loader(loader) { } void PixmapLoaderThread::run() { static const qreal widthFactor = Settings::widthFactor(); static const qreal heightFactor = Settings::heightFactor(); QString name = m_loader->dequeue(); while (!name.isEmpty()) { QImage image(":images/weather_elements/" + name + ".png"); if (!image.isNull()) { QSize size(widthFactor * image.size().width(), heightFactor * image.size().height()); if (size.width() && size.height()) image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } emit imageIsReady(name, image); name = m_loader->dequeue(); } deleteLater(); } // PixmapLoader PixmapLoader::PixmapLoader(QObject *parent) : QObject(parent) , m_thread(0) { } void PixmapLoader::load(const QString &name) { instance()->enqueue(name); } PixmapLoader *PixmapLoader::instance() { static PixmapLoader * const result(new PixmapLoader()); return result; } void PixmapLoader::connectToOnIdleSignal(QObject *receiver, const char *method) { QObject::connect(instance(), SIGNAL(onIdle()), receiver, method, Qt::QueuedConnection); } void PixmapLoader::disconnectReceiver(QObject *receiver) { instance()->disconnect(receiver); } QPixmap PixmapLoader::getPic(const QString &name) { PixmapLoader *obj = instance(); QMutexLocker locker(&obj->m_mutex); return obj->m_store.contains(name) ? obj->m_store[name] : QPixmap(); } void PixmapLoader::enqueue(const QString &name) { QMutexLocker locker(&m_mutex); if (m_queue.indexOf(name) >= 0 || m_currentImages.indexOf(name) >= 0 || m_store.contains(name)) return; m_queue.append(name); if (!m_thread) { m_thread = new PixmapLoaderThread(this); connect(m_thread, SIGNAL(imageIsReady(QString,QImage)), this, SLOT(imageIsReady(QString,QImage))); m_thread->start(); } m_condition.wakeOne(); } QString PixmapLoader::doDequeue() { QString name = m_queue.isEmpty() ? QString() : m_queue.takeAt(0); while (!name.isEmpty() && (m_currentImages.indexOf(name) >= 0 || m_store.contains(name))) name = m_queue.isEmpty() ? QString() : m_queue.takeAt(0); if (!name.isEmpty()) m_currentImages.append(name); return name; } QString PixmapLoader::dequeue() { static const int waitTime = 60000; QMutexLocker locker(&m_mutex); QString result; do result = doDequeue(); while (result.isEmpty() && m_condition.wait(&m_mutex, waitTime)); if (result.isEmpty()) { m_thread = 0; } return result; } void PixmapLoader::imageIsReady(const QString &name, QImage image) { QMutexLocker locker(&m_mutex); QPixmap pixmap = QPixmap::fromImage(image, Qt::ColorOnly); if (!pixmap.isNull()) m_store[name] = pixmap; m_currentImages.removeAll(name); if (m_currentImages.isEmpty() && m_queue.isEmpty()) emit onIdle(); }