summaryrefslogtreecommitdiffstats
path: root/weather/src/pixmaploader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'weather/src/pixmaploader.cpp')
-rw-r--r--weather/src/pixmaploader.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/weather/src/pixmaploader.cpp b/weather/src/pixmaploader.cpp
new file mode 100644
index 0000000..e60cef4
--- /dev/null
+++ b/weather/src/pixmaploader.cpp
@@ -0,0 +1,125 @@
+#include "pixmaploader.h"
+#include "settings.h"
+#include <QMutexLocker>
+
+#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();
+}