aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2014-06-30 11:29:31 +0200
committerFriedemann Kleint <Friedemann.Kleint@digia.com>2014-07-02 12:43:43 +0200
commit7bb27be8c5ce9a67a413022d627d9580cddbe64e (patch)
tree3284f172868869a220d801297c55f67015d17497 /src
parentafd0051c5cfb6ccb1d361d89c36b9c494c29ec5e (diff)
Refactor QQuickIconLoader.
Instead using a QObject with a single icon member variable that needs to be instantiated for each task bar button, introduce a static load function that takes a member function pointer accepting a QVariant. For synchronous requests, invoke it immediately; connect it to a slot for network requests. Task-number: QTBUG-36730 Change-Id: Ic70422d98d0bc3d486b32fb3534400b9fff8d324 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/imports/winextras/qquickiconloader.cpp147
-rw-r--r--src/imports/winextras/qquickiconloader_p.h76
-rw-r--r--src/imports/winextras/qquicktaskbarbutton.cpp26
-rw-r--r--src/imports/winextras/qquicktaskbarbutton_p.h6
-rw-r--r--src/imports/winextras/qquickthumbnailtoolbutton.cpp24
-rw-r--r--src/imports/winextras/qquickthumbnailtoolbutton_p.h7
6 files changed, 178 insertions, 108 deletions
diff --git a/src/imports/winextras/qquickiconloader.cpp b/src/imports/winextras/qquickiconloader.cpp
index e1b7506..5ed7445 100644
--- a/src/imports/winextras/qquickiconloader.cpp
+++ b/src/imports/winextras/qquickiconloader.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Ivan Vizir <define-true-false@yandex.com>
- ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWinExtras module of the Qt Toolkit.
@@ -42,105 +42,110 @@
#include "qquickiconloader_p.h"
-#include <QUrl>
#include <QQmlEngine>
#include <QNetworkAccessManager>
#include <QFileInfo>
#include <QNetworkRequest>
#include <QNetworkReply>
-#include <QPixmap>
#include <QQuickImageProvider>
#include <QQmlFile>
#include <qt_windows.h>
-#include <QDebug>
QT_BEGIN_NAMESPACE
-QQuickIconLoader::QQuickIconLoader(QObject *parent) :
- QObject(parent)
+QVariant QQuickIconLoader::loadFromFile(const QUrl &url, QVariant::Type type)
{
-}
-
-void QQuickIconLoader::load(const QUrl &url, QQmlEngine *engine)
-{
- m_icon = QIcon();
- QString scheme = url.scheme();
- if (scheme == QLatin1String("qrc") || scheme == QLatin1String("file"))
- loadFromFile(url);
- else if (scheme == QLatin1String("http") || scheme == QLatin1String("https"))
- loadFromNetwork(url, engine);
- else if (scheme == QLatin1String("image"))
- loadFromImageProvider(url, engine);
-}
-
-QIcon QQuickIconLoader::icon() const
-{
- return m_icon;
-}
-
-void QQuickIconLoader::onRequestFinished(QNetworkReply *reply)
-{
- disconnect(reply->manager(), 0, this, 0);
- if (reply->error() == QNetworkReply::NoError) {
- QByteArray data = reply->readAll();
- QPixmap pixmap;
- if (pixmap.loadFromData(data)) {
- m_icon = QIcon(pixmap);
- emit finished();
- }
- } else {
- qWarning().nospace() << "Cannot load " << reply->url().toString() << " (" << qPrintable(reply->errorString()) << ")";
- }
- reply->deleteLater();
-}
-
-void QQuickIconLoader::loadFromFile(const QUrl &url)
-{
- QString path = QQmlFile::urlToLocalFileOrQrc(url);
+ const QString path = QQmlFile::urlToLocalFileOrQrc(url);
if (QFileInfo(path).exists()) {
- m_icon = QIcon(path);
- emit finished();
+ switch (type) {
+ case QMetaType::QIcon:
+ return QVariant(QIcon(path));
+ case QMetaType::QPixmap:
+ return QVariant(QPixmap(path));
+ default:
+ qWarning("%s: Unsupported type: %d", Q_FUNC_INFO, int(type));
+ break;
+ }
}
+ return QVariant();
}
-void QQuickIconLoader::loadFromNetwork(const QUrl &url, QQmlEngine *engine)
+QNetworkReply *QQuickIconLoader::loadFromNetwork(const QUrl &url, const QQmlEngine *engine)
{
- QNetworkRequest request(url);
- QNetworkAccessManager *manager = engine->networkAccessManager();
- connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(onRequestFinished(QNetworkReply*)));
- manager->get(request);
+ return engine->networkAccessManager()->get(QNetworkRequest(url));
}
-static inline QString imageProviderId(const QUrl &url)
-{
- return url.host();
-}
-
-static inline QString imageId(const QUrl &url)
-{
- return url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
-}
-
-void QQuickIconLoader::loadFromImageProvider(const QUrl &url, QQmlEngine *engine)
+QVariant QQuickIconLoader::loadFromImageProvider(const QUrl &url, const QQmlEngine *engine,
+ QVariant::Type type, QSize requestedSize)
{
const QString providerId = url.host();
const QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(providerId));
QSize size;
- QSize requestSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
+ if (!requestedSize.isValid())
+ requestedSize = QSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
if (provider)
imageType = provider->imageType();
- if (imageType == QQuickImageProvider::Image) {
- QImage image = provider->requestImage(imageId, &size, requestSize);
+ QPixmap pixmap;
+ switch (imageType) {
+ case QQuickImageProvider::Image: {
+ QImage image = provider->requestImage(imageId, &size, requestedSize);
if (!image.isNull())
- m_icon = QIcon(QPixmap::fromImage(image));
- } else if (imageType == QQuickImageProvider::Pixmap) {
- QPixmap pixmap = provider->requestPixmap(imageId, &size, requestSize);
- if (!pixmap.isNull())
- m_icon = QIcon(pixmap);
+ pixmap = QPixmap::fromImage(image);
+ }
+ break;
+ case QQuickImageProvider::Pixmap:
+ pixmap = provider->requestPixmap(imageId, &size, requestedSize);
+ break;
+ default:
+ break;
}
- emit finished();
+ if (!pixmap.isNull()) {
+ switch (type) {
+ case QMetaType::QIcon:
+ return QVariant(QIcon(pixmap));
+ case QMetaType::QPixmap:
+ return QVariant(pixmap);
+ default:
+ qWarning("%s: Unsupported type: %d", Q_FUNC_INFO, int(type));
+ break;
+ }
+ }
+ return QVariant();
+}
+
+QQuickIconLoaderNetworkReplyHandler::QQuickIconLoaderNetworkReplyHandler(QNetworkReply *reply, QVariant::Type type)
+ : QObject(reply)
+ , m_type(type)
+{
+ connect(reply, &QNetworkReply::finished, this, &QQuickIconLoaderNetworkReplyHandler::onRequestFinished);
+}
+
+void QQuickIconLoaderNetworkReplyHandler::onRequestFinished()
+{
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ Q_ASSERT(reply);
+ if (reply->error() != QNetworkReply::NoError) {
+ qWarning() << Q_FUNC_INFO << reply->url() << "failed:" << reply->errorString();
+ return;
+ }
+ const QByteArray data = reply->readAll();
+ QPixmap pixmap;
+ if (pixmap.loadFromData(data)) {
+ switch (m_type) {
+ case QMetaType::QIcon:
+ emit finished(QVariant(QIcon(pixmap)));
+ break;
+ case QMetaType::QPixmap:
+ emit finished(QVariant(pixmap));
+ break;
+ default:
+ qWarning("%s: Unsupported type: %d", Q_FUNC_INFO, int(m_type));
+ break;
+ }
+ }
+ reply->deleteLater();
}
QT_END_NAMESPACE
diff --git a/src/imports/winextras/qquickiconloader_p.h b/src/imports/winextras/qquickiconloader_p.h
index 0df9b01..3d4d13d 100644
--- a/src/imports/winextras/qquickiconloader_p.h
+++ b/src/imports/winextras/qquickiconloader_p.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Ivan Vizir <define-true-false@yandex.com>
- ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWinExtras module of the Qt Toolkit.
@@ -44,7 +44,11 @@
#define QQUICKICONLOADER_P_H
#include <QObject>
+#include <QVariant>
+#include <QUrl>
#include <QIcon>
+#include <QPixmap>
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -52,29 +56,77 @@ class QIcon;
class QQmlEngine;
class QNetworkReply;
-class QQuickIconLoader : public QObject
+class QQuickIconLoader
+{
+public:
+ enum LoadResult {
+ LoadOk,
+ LoadError,
+ LoadNetworkRequestStarted,
+ };
+
+ // Load a QIcon (pass type = QMetaType::QIcon) or a QPixmap (pass type =
+ // QMetaType::QPixmap) from url. The function takes an object and member
+ // function pointer to a slot accepting a QVariant. For resources that can
+ // loaded synchronously ("file", "qrc" or "image"), the member function pointer
+ // will be invoked immediately with the result. For network resources, it will be
+ // connected to an object handling the network reply and invoked once it finishes.
+ template <typename Object>
+ static LoadResult load(const QUrl &url, const QQmlEngine *engine,
+ QVariant::Type type, const QSize &requestedSize,
+ Object *receiver, void (Object::*function)(const QVariant &));
+
+private:
+ QQuickIconLoader() {}
+ static QVariant loadFromFile(const QUrl &url, QVariant::Type type);
+ static QVariant loadFromImageProvider(const QUrl &url, const QQmlEngine *engine,
+ QVariant::Type type, QSize requestedSize);
+ static QNetworkReply *loadFromNetwork(const QUrl &url, const QQmlEngine *engine);
+};
+
+// Internal handler which loads the resource once QNetworkReply finishes
+class QQuickIconLoaderNetworkReplyHandler : public QObject
{
Q_OBJECT
public:
- explicit QQuickIconLoader(QObject *parent = 0);
- void load(const QUrl &url, QQmlEngine *engine);
- QIcon icon() const;
+ explicit QQuickIconLoaderNetworkReplyHandler(QNetworkReply *reply, QVariant::Type);
Q_SIGNALS:
- void finished();
+ void finished(const QVariant &);
private Q_SLOTS:
- void onRequestFinished(QNetworkReply*);
+ void onRequestFinished();
private:
- void loadFromFile(const QUrl &url);
- void loadFromNetwork(const QUrl &url, QQmlEngine *engine);
- void loadFromImageProvider(const QUrl &url, QQmlEngine *engine);
-
- QIcon m_icon;
+ const QVariant::Type m_type;
};
+template <typename Object>
+QQuickIconLoader::LoadResult
+ QQuickIconLoader::load(const QUrl &url, const QQmlEngine *engine,
+ QVariant::Type type, const QSize &requestedSize,
+ Object *receiver, void (Object::*function)(const QVariant &))
+{
+ const QString scheme = url.scheme();
+ if (scheme.startsWith(QLatin1String("http"))) {
+ if (QNetworkReply *reply = QQuickIconLoader::loadFromNetwork(url, engine)) {
+ QQuickIconLoaderNetworkReplyHandler *handler = new QQuickIconLoaderNetworkReplyHandler(reply, type);
+ QObject::connect(handler, &QQuickIconLoaderNetworkReplyHandler::finished, receiver, function);
+ return LoadNetworkRequestStarted;
+ }
+ return LoadError;
+ }
+ const QVariant resource = scheme == QLatin1String("image")
+ ? QQuickIconLoader::loadFromImageProvider(url, engine, type, requestedSize)
+ : QQuickIconLoader::loadFromFile(url, type); // qrc, file
+ if (resource.isValid()) {
+ (receiver->*function)(resource);
+ return LoadOk;
+ }
+ return LoadError;
+}
+
QT_END_NAMESPACE
#endif // QQUICKICONLOADER_P_H
diff --git a/src/imports/winextras/qquicktaskbarbutton.cpp b/src/imports/winextras/qquicktaskbarbutton.cpp
index 97e0765..b644b78 100644
--- a/src/imports/winextras/qquicktaskbarbutton.cpp
+++ b/src/imports/winextras/qquicktaskbarbutton.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Ivan Vizir <define-true-false@yandex.com>
- ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWinExtras module of the Qt Toolkit.
@@ -41,7 +41,10 @@
****************************************************************************/
#include "qquicktaskbarbutton_p.h"
+#include "qquickiconloader_p.h"
+
#include <QQuickWindow>
+#include <QVariant>
QT_BEGIN_NAMESPACE
@@ -73,7 +76,6 @@ QT_BEGIN_NAMESPACE
QQuickTaskbarOverlay::QQuickTaskbarOverlay(QWinTaskbarButton *button, QObject *parent) :
QObject(parent), m_button(button)
{
- connect(&m_loader, SIGNAL(finished()), SLOT(iconLoaded()));
}
QUrl QQuickTaskbarOverlay::iconSource() const
@@ -83,10 +85,20 @@ QUrl QQuickTaskbarOverlay::iconSource() const
void QQuickTaskbarOverlay::setIconSource(const QUrl &iconSource)
{
- if (m_iconSource != iconSource) {
+ if (m_iconSource == iconSource)
+ return;
+
+ if (iconSource.isEmpty()) {
+ m_button->clearOverlayIcon();
+ m_iconSource = iconSource;
+ emit iconSourceChanged();
+ return;
+ }
+
+ if (QQuickIconLoader::load(iconSource, qmlEngine(parent()), QVariant::Icon, QSize(),
+ this, &QQuickTaskbarOverlay::iconLoaded) != QQuickIconLoader::LoadError) {
m_iconSource = iconSource;
emit iconSourceChanged();
- m_loader.load(m_iconSource, qmlEngine(parent()));
}
}
@@ -103,11 +115,9 @@ void QQuickTaskbarOverlay::setAccessibleDescription(const QString &description)
}
}
-void QQuickTaskbarOverlay::iconLoaded()
+void QQuickTaskbarOverlay::iconLoaded(const QVariant &value)
{
- QIcon icon = m_loader.icon();
- if (!icon.isNull())
- m_button->setOverlayIcon(icon);
+ m_button->setOverlayIcon(value.value<QIcon>());
}
QQuickTaskbarButton::QQuickTaskbarButton(QQuickItem *parent) : QQuickItem(parent),
diff --git a/src/imports/winextras/qquicktaskbarbutton_p.h b/src/imports/winextras/qquicktaskbarbutton_p.h
index d24947d..2849dab 100644
--- a/src/imports/winextras/qquicktaskbarbutton_p.h
+++ b/src/imports/winextras/qquicktaskbarbutton_p.h
@@ -47,10 +47,9 @@
#include <QWinTaskbarButton>
#include <QWinTaskbarProgress>
-#include "qquickiconloader_p.h"
-
QT_BEGIN_NAMESPACE
+class QVariant;
class QQuickTaskbarButtonPrivate;
class QQuickTaskbarOverlay : public QObject
@@ -73,11 +72,10 @@ Q_SIGNALS:
void accessibleDescriptionChanged();
private Q_SLOTS:
- void iconLoaded();
+ void iconLoaded(const QVariant &);
private:
QUrl m_iconSource;
- QQuickIconLoader m_loader;
QWinTaskbarButton *m_button;
};
diff --git a/src/imports/winextras/qquickthumbnailtoolbutton.cpp b/src/imports/winextras/qquickthumbnailtoolbutton.cpp
index 7f84988..31875e7 100644
--- a/src/imports/winextras/qquickthumbnailtoolbutton.cpp
+++ b/src/imports/winextras/qquickthumbnailtoolbutton.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Ivan Vizir <define-true-false@yandex.com>
- ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWinExtras module of the Qt Toolkit.
@@ -41,6 +41,7 @@
****************************************************************************/
#include "qquickthumbnailtoolbutton_p.h"
+#include "qquickiconloader_p.h"
#include <QWinThumbnailToolButton>
@@ -66,7 +67,6 @@ QQuickThumbnailToolButton::QQuickThumbnailToolButton(QObject *parent) :
QObject(parent), m_button(new QWinThumbnailToolButton(this))
{
connect(m_button, SIGNAL(clicked()), SIGNAL(clicked()));
- connect(&m_loader, SIGNAL(finished()), SLOT(iconLoaded()));
}
QQuickThumbnailToolButton::~QQuickThumbnailToolButton()
@@ -80,10 +80,19 @@ QQuickThumbnailToolButton::~QQuickThumbnailToolButton()
*/
void QQuickThumbnailToolButton::setIconSource(const QUrl &iconSource)
{
- if (m_iconSource != iconSource) {
+ if (m_iconSource == iconSource)
+ return;
+
+ if (iconSource.isEmpty()) {
+ m_button->setIcon(QIcon());
+ m_iconSource = iconSource;
+ emit iconSourceChanged();
+ }
+
+ if (QQuickIconLoader::load(iconSource, qmlEngine(this), QVariant::Icon, QSize(),
+ this, &QQuickThumbnailToolButton::iconLoaded) != QQuickIconLoader::LoadError) {
m_iconSource = iconSource;
emit iconSourceChanged();
- m_loader.load(m_iconSource, qmlEngine(this));
}
}
@@ -213,11 +222,10 @@ bool QQuickThumbnailToolButton::isFlat() const
return m_button->isFlat();
}
-void QQuickThumbnailToolButton::iconLoaded()
+void QQuickThumbnailToolButton::iconLoaded(const QVariant &value)
{
- QIcon icon = m_loader.icon();
- if (!icon.isNull())
- m_button->setIcon(icon);
+ if (value.isValid())
+ m_button->setIcon(value.value<QIcon>());
}
QT_END_NAMESPACE
diff --git a/src/imports/winextras/qquickthumbnailtoolbutton_p.h b/src/imports/winextras/qquickthumbnailtoolbutton_p.h
index 82fcdae..8235206 100644
--- a/src/imports/winextras/qquickthumbnailtoolbutton_p.h
+++ b/src/imports/winextras/qquickthumbnailtoolbutton_p.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Ivan Vizir <define-true-false@yandex.com>
- ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWinExtras module of the Qt Toolkit.
@@ -47,8 +47,6 @@
#include <QWinThumbnailToolBar>
#include <QUrl>
-#include "qquickiconloader_p.h"
-
QT_BEGIN_NAMESPACE
class QQuickThumbnailToolButton : public QObject
@@ -92,12 +90,11 @@ Q_SIGNALS:
void flatChanged();
private Q_SLOTS:
- void iconLoaded();
+ void iconLoaded(const QVariant &);
private:
QUrl m_iconSource;
QWinThumbnailToolButton *m_button;
- QQuickIconLoader m_loader;
friend class QQuickThumbnailToolBar;
};