summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/declarative/qmlmodels.qdoc7
-rw-r--r--src/declarative/qml/qml.pri11
-rw-r--r--src/declarative/qml/qmlengine.cpp62
-rw-r--r--src/declarative/qml/qmlengine.h8
-rw-r--r--src/declarative/qml/qmlengine_p.h3
-rw-r--r--src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp93
-rw-r--r--src/declarative/qml/qmlnetworkaccessmanagerfactory.h70
-rw-r--r--src/declarative/util/qmlanimation.cpp6
-rw-r--r--src/declarative/util/qmllistmodel.cpp10
-rw-r--r--src/declarative/util/qmlpixmapcache.cpp321
-rw-r--r--src/declarative/util/qmlpixmapcache_p.h10
-rw-r--r--tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp6
-rw-r--r--tests/benchmarks/declarative/declarative.pro2
-rw-r--r--tests/benchmarks/declarative/qmlpainting/qmlpainting.pro6
-rw-r--r--tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp574
-rw-r--r--tests/benchmarks/declarative/signalemission/signalemission.pro7
-rw-r--r--tests/benchmarks/declarative/signalemission/tst_signalemission.cpp160
-rw-r--r--tests/benchmarks/declarative/text/text.pro7
-rw-r--r--tests/benchmarks/declarative/text/tst_text.cpp260
-rw-r--r--tools/qmlviewer/qmlviewer.cpp162
-rw-r--r--tools/qmlviewer/qmlviewer.h6
21 files changed, 572 insertions, 1219 deletions
diff --git a/doc/src/declarative/qmlmodels.qdoc b/doc/src/declarative/qmlmodels.qdoc
index 2dc24fe..322f225 100644
--- a/doc/src/declarative/qmlmodels.qdoc
+++ b/doc/src/declarative/qmlmodels.qdoc
@@ -58,6 +58,13 @@ property in the delegate, the roles are usually accessed unqualified.
A special \e index role containing the index of the item in the model
is also available.
+\e Note: the index role will be set to -1 if the item is removed from
+the model. If you bind to the index role, be sure that the logic
+accounts for the possibility of index being -1, i.e. that the item
+is no longer valid. Usually the item will shortly be destroyed, but
+it is possible to delay delegate destruction in some views via a delayRemove
+attached property.
+
Models that do not have named roles will have the data provided via
the \e modelData role. The \e modelData role is also provided for
Models that have only one role. In this case the \e modelData role
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 6f2f57f..cd2fbff 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -1,5 +1,4 @@
INCLUDEPATH += $$PWD
-
SOURCES += \
$$PWD/qmlparser.cpp \
$$PWD/qmlinstruction.cpp \
@@ -50,8 +49,8 @@ SOURCES += \
$$PWD/qmlvaluetypescriptclass.cpp \
$$PWD/qmltypenamescriptclass.cpp \
$$PWD/qmllistscriptclass.cpp \
- $$PWD/qmlworkerscript.cpp
-
+ $$PWD/qmlworkerscript.cpp \
+ $$PWD/qmlnetworkaccessmanagerfactory.cpp
HEADERS += \
$$PWD/qmlparser_p.h \
$$PWD/qmlglobal_p.h \
@@ -117,10 +116,8 @@ HEADERS += \
$$PWD/qmllistscriptclass_p.h \
$$PWD/qmlworkerscript_p.h \
$$PWD/qmlscriptclass_p.h \
- $$PWD/qmlguard_p.h
-
+ $$PWD/qmlguard_p.h \
+ $$PWD/qmlnetworkaccessmanagerfactory.h
QT += sql
-
include(parser/parser.pri)
include(rewriter/rewriter.pri)
-
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 5a40468..b3ac1bb 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -64,6 +64,7 @@
#include "qmlworkerscript_p.h"
#include "qmlcomponent_p.h"
#include "qmlscriptclass_p.h"
+#include "qmlnetworkaccessmanagerfactory.h"
#include <qfxperf_p_p.h>
@@ -121,7 +122,8 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
contextClass(0), sharedContext(0), sharedScope(0), objectClass(0), valueTypeClass(0),
globalClass(0), cleanup(0), erroredBindings(0), inProgressCreations(0),
scriptEngine(this), workerScriptEngine(0), componentAttacheds(0), inBeginCreate(false),
- networkAccessManager(0), typeManager(e), uniqueId(1)
+ networkAccessManager(0), networkAccessManagerFactory(0), accessManagerValid(false),
+ typeManager(e), uniqueId(1)
{
globalClass = new QmlGlobalScriptClass(&scriptEngine);
fileImportPath.append(QLibraryInfo::location(QLibraryInfo::DataPath)+QDir::separator()+QLatin1String("qml"));
@@ -386,34 +388,64 @@ QmlContext *QmlEngine::rootContext()
}
/*!
- Sets the common QNetworkAccessManager, \a network, used by all QML elements
- instantiated by this engine.
+ Sets the \a factory to use for creating QNetworkAccessManager(s).
+
+ QNetworkAccessManager is used for all network access by QML.
+ By implementing a factory it is possible to create custom
+ QNetworkAccessManager with specialized caching, proxy and
+ cookie support.
+*/
+void QmlEngine::setNetworkAccessManagerFactory(QmlNetworkAccessManagerFactory *factory)
+{
+ Q_D(QmlEngine);
+ d->networkAccessManagerFactory = factory;
+}
- If the parent of \a network is this engine, the engine takes ownership and
- will delete it as needed. Otherwise, ownership remains with the caller.
+/*!
+ Returns the current QmlNetworkAccessManagerFactory.
- This method should only be called before any QmlComponents are instantiated.
+ \sa setNetworkAccessManagerFactory()
*/
-void QmlEngine::setNetworkAccessManager(QNetworkAccessManager *network)
+QmlNetworkAccessManagerFactory *QmlEngine::networkAccessManagerFactory() const
+{
+ Q_D(const QmlEngine);
+ return d->networkAccessManagerFactory;
+}
+
+void QmlEngine::namInvalidated()
{
Q_D(QmlEngine);
- if (d->networkAccessManager && d->networkAccessManager->parent() == this)
- delete d->networkAccessManager;
- d->networkAccessManager = network;
+ d->accessManagerValid = false;
}
/*!
- Returns the common QNetworkAccessManager used by all QML elements
+ Returns a common QNetworkAccessManager which can be used by any QML element
instantiated by this engine.
- The default implements no caching, cookiejar, etc., just a default
- QNetworkAccessManager.
+ If a QmlNetworkAccessManagerFactory has been set and a QNetworkAccessManager
+ has not yet been created, the QmlNetworkAccessManagerFactory will be used
+ to create the QNetworkAccessManager; otherwise the returned QNetworkAccessManager
+ will have no proxy or cache set.
+
+ \sa setNetworkAccessManagerFactory()
*/
QNetworkAccessManager *QmlEngine::networkAccessManager() const
{
Q_D(const QmlEngine);
- if (!d->networkAccessManager)
- d->networkAccessManager = new QNetworkAccessManager(const_cast<QmlEngine*>(this));
+ if (!d->accessManagerValid) {
+ delete d->networkAccessManagerFactory;
+ d->networkAccessManagerFactory = 0;
+ }
+ if (!d->networkAccessManager) {
+ if (d->networkAccessManagerFactory) {
+ connect(d->networkAccessManagerFactory, SIGNAL(invalidated())
+ , this, SLOT(namInvalidated()), Qt::UniqueConnection);
+ d->networkAccessManager = d->networkAccessManagerFactory->create(const_cast<QmlEngine*>(this));
+ } else {
+ d->networkAccessManager = new QNetworkAccessManager(const_cast<QmlEngine*>(this));
+ }
+ d->accessManagerValid = true;
+ }
return d->networkAccessManager;
}
diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h
index 7cbbcac..b9ec277 100644
--- a/src/declarative/qml/qmlengine.h
+++ b/src/declarative/qml/qmlengine.h
@@ -63,6 +63,7 @@ class QUrl;
class QScriptEngine;
class QScriptContext;
class QNetworkAccessManager;
+class QmlNetworkAccessManagerFactory;
class Q_DECLARATIVE_EXPORT QmlEngine : public QObject
{
Q_PROPERTY(QString offlineStoragePath READ offlineStoragePath WRITE setOfflineStoragePath)
@@ -77,7 +78,9 @@ public:
void addImportPath(const QString& dir);
- void setNetworkAccessManager(QNetworkAccessManager *);
+ void setNetworkAccessManagerFactory(QmlNetworkAccessManagerFactory *);
+ QmlNetworkAccessManagerFactory *networkAccessManagerFactory() const;
+
QNetworkAccessManager *networkAccessManager() const;
void setOfflineStoragePath(const QString& dir);
@@ -92,6 +95,9 @@ public:
Q_SIGNALS:
void quit ();
+private Q_SLOTS:
+ void namInvalidated();
+
private:
Q_DECLARE_PRIVATE(QmlEngine)
};
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 85e8c80..6f62b40 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -92,6 +92,7 @@ class QmlValueTypeScriptClass;
class QScriptEngineDebugger;
class QNetworkReply;
class QNetworkAccessManager;
+class QmlNetworkAccessManagerFactory;
class QmlAbstractBinding;
class QScriptDeclarativeClass;
class QmlTypeNameScriptClass;
@@ -209,6 +210,8 @@ public:
bool inBeginCreate;
mutable QNetworkAccessManager *networkAccessManager;
+ mutable QmlNetworkAccessManagerFactory *networkAccessManagerFactory;
+ mutable bool accessManagerValid;
QmlCompositeTypeManager typeManager;
QStringList fileImportPath;
diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp
new file mode 100644
index 0000000..6ae20de
--- /dev/null
+++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlnetworkaccessmanagerfactory.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QmlNetworkAccessManagerFactory
+ \brief The QmlNetworkAccessManagerFactory class provides a factory for QNetworkAccessManager
+
+ QNetworkAccessManager is used for all network access by QML.
+ By implementing a factory it is possible to create custom
+ QNetworkAccessManager with specialized caching, proxy and
+ cookie support.
+
+ To implement a factory, subclass QmlNetworkAccessManagerFactory and implement
+ the create() method.
+
+ If the created QNetworkAccessManager becomes invalid, due to a
+ change in proxy settings, for example, call the invalidate() method.
+ This will cause all QNetworkAccessManagers to be recreated.
+
+ Note: the create() method may be called by multiple threads, so ensure the
+ implementation of this method is reentrant.
+*/
+QmlNetworkAccessManagerFactory::~QmlNetworkAccessManagerFactory()
+{
+}
+
+/*!
+ \fn QNetworkAccessManager *QmlNetworkAccessManagerFactory::create(QObject *parent)
+
+ Implement this method to create a QNetworkAccessManager with \a parent.
+ This allows proxies, caching and cookie support to be setup appropriately.
+
+ Note: this method may be called by multiple threads, so ensure the
+ implementation of this method is reentrant.
+*/
+
+/*!
+ Invalidates all currently created QNetworkAccessManager(s) which
+ will cause create() to be called for subsequent network access.
+*/
+void QmlNetworkAccessManagerFactory::invalidate()
+{
+ emit invalidated();
+}
+
+/*!
+ \internal
+ \fn QmlNetworkAccessManagerFactory::invalidated()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.h b/src/declarative/qml/qmlnetworkaccessmanagerfactory.h
new file mode 100644
index 0000000..f64918b
--- /dev/null
+++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLNETWORKACCESSMANAGERFACTORY_H
+#define QMLNETWORKACCESSMANAGERFACTORY_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QNetworkAccessManager;
+class Q_DECLARATIVE_EXPORT QmlNetworkAccessManagerFactory : public QObject
+{
+ Q_OBJECT
+public:
+ virtual ~QmlNetworkAccessManagerFactory();
+ void invalidate();
+ virtual QNetworkAccessManager *create(QObject *parent) = 0;
+
+Q_SIGNALS:
+ void invalidated();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLNETWORKACCESSMANAGERFACTORY_H
diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp
index f5333a6..efb4159 100644
--- a/src/declarative/util/qmlanimation.cpp
+++ b/src/declarative/util/qmlanimation.cpp
@@ -1660,10 +1660,12 @@ void QmlPropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
\inherits Animation
\brief The PropertyAnimation element allows you to animate property changes.
- Animate a size property over 200ms, from its current size to 20-by-20:
+ Animate theObject's size property over 200ms, from its current size to 20-by-20:
\code
- PropertyAnimation { property: "size"; to: "20x20"; duration: 200 }
+ PropertyAnimation { target: theObject; property: "size"; to: "20x20"; duration: 200 }
\endcode
+
+ For an introduction to animation in QML, see \l{QML Animation}.
*/
QmlPropertyAnimation::QmlPropertyAnimation(QObject *parent)
diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp
index e975a5f..8c70539 100644
--- a/src/declarative/util/qmllistmodel.cpp
+++ b/src/declarative/util/qmllistmodel.cpp
@@ -405,7 +405,7 @@ QHash<int,QVariant> QmlListModel::data(int index, const QList<int> &roles) const
{
checkRoles();
QHash<int, QVariant> rv;
- if (index >= count())
+ if (index >= count() || index < 0)
return rv;
ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
@@ -430,7 +430,7 @@ QVariant QmlListModel::data(int index, int role) const
{
checkRoles();
QVariant rv;
- if (index >= count())
+ if (index >= count() || index < 0)
return rv;
ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
@@ -643,7 +643,7 @@ void QmlListModel::append(const QScriptValue& valuemap)
*/
QScriptValue QmlListModel::get(int index) const
{
- if (index >= count()) {
+ if (index >= count() || index < 0) {
qmlInfo(this) << tr("get: index %1 out of range").arg(index);
return 0;
}
@@ -680,7 +680,7 @@ void QmlListModel::set(int index, const QScriptValue& valuemap)
qmlInfo(this) << tr("set: value is not an object");
return;
}
- if ( !_root || index > _root->values.count()) {
+ if ( !_root || index > _root->values.count() || index < 0) {
qmlInfo(this) << tr("set: index %1 out of range").arg(index);
return;
}
@@ -719,7 +719,7 @@ void QmlListModel::set(int index, const QScriptValue& valuemap)
*/
void QmlListModel::setProperty(int index, const QString& property, const QVariant& value)
{
- if ( !_root || index >= _root->values.count()) {
+ if ( !_root || index >= _root->values.count() || index < 0) {
qmlInfo(this) << tr("set: index %1 out of range").arg(index);
return;
}
diff --git a/src/declarative/util/qmlpixmapcache.cpp b/src/declarative/util/qmlpixmapcache.cpp
index 4c1d448..c058408 100644
--- a/src/declarative/util/qmlpixmapcache.cpp
+++ b/src/declarative/util/qmlpixmapcache.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qmlpixmapcache_p.h"
+#include "qmlnetworkaccessmanagerfactory.h"
#include "qfxperf_p_p.h"
@@ -57,6 +58,15 @@
#include <QWaitCondition>
#include <QtCore/qdebug.h>
#include <private/qobject_p.h>
+#include <QSslError>
+
+#ifdef Q_OS_LINUX
+#include <pthread.h>
+#include <linux/sched.h>
+#endif
+
+// Maximum number of simultaneous image requests to send.
+static const int maxImageRequestCount = 8;
QT_BEGIN_NAMESPACE
@@ -69,105 +79,231 @@ class QmlImageReader : public QThread
{
Q_OBJECT
public:
- QmlImageReader(QObject *parent=0);
+ QmlImageReader(QmlEngine *eng);
~QmlImageReader();
- void read(QmlPixmapReply *rep);
+ QmlPixmapReply *getImage(const QUrl &url);
void cancel(QmlPixmapReply *rep);
+ static QmlImageReader *instance(QmlEngine *engine);
+
protected:
void run();
+ bool event(QEvent *event);
-private:
- struct Job {
- Job() : reply(0), error(false) {}
- QmlPixmapReply *reply;
- QImage img;
- bool error;
- };
+private slots:
+ void networkRequestDone();
+ void namInvalidated() {
+ accessManagerValid = false;
+ }
- void loadImage(Job &job);
+private:
+ QNetworkAccessManager *networkAccessManager() {
+ if (!accessManagerValid) {
+ delete accessManager;
+ accessManager = 0;
+ }
+ if (!accessManager) {
+ if (engine && engine->networkAccessManagerFactory()) {
+ connect(engine->networkAccessManagerFactory(), SIGNAL(invalidated())
+ , this, SLOT(namInvalidated()), Qt::UniqueConnection);
+ accessManager = engine->networkAccessManagerFactory()->create(this);
+ } else {
+ accessManager = new QNetworkAccessManager(this);
+ }
+ accessManagerValid = true;
+ }
+ return accessManager;
+ }
- QList<Job> jobs;
+ QList<QmlPixmapReply*> jobs;
+ QList<QmlPixmapReply*> cancelled;
+ QHash<QNetworkReply*,QmlPixmapReply*> replies;
+ QNetworkAccessManager *accessManager;
+ bool accessManagerValid;
+ QmlEngine *engine;
QMutex mutex;
- QWaitCondition haveJob;
- bool quit;
+ static QHash<QmlEngine *,QmlImageReader*> readers;
};
-class QmlImageDecodeEvent : public QEvent
+QHash<QmlEngine *,QmlImageReader*> QmlImageReader::readers;
+
+class QmlImageReaderEvent : public QEvent
{
public:
- QmlImageDecodeEvent(bool err, QImage &img) : QEvent(QEvent::User), error(err), image(img) {}
+ enum ReadError { NoError, Loading, Decoding };
- bool error;
+ QmlImageReaderEvent(QmlImageReaderEvent::ReadError err, QImage &img)
+ : QEvent(QEvent::User), error(err), image(img) {}
+
+ ReadError error;
QImage image;
};
-Q_GLOBAL_STATIC(QmlImageReader, qmlImageReader)
-
-QmlImageReader::QmlImageReader(QObject *parent) : QThread(parent), quit(false)
+QmlImageReader::QmlImageReader(QmlEngine *eng)
+ : QThread(eng), accessManager(0), accessManagerValid(false), engine(eng)
{
start(QThread::LowPriority);
}
QmlImageReader::~QmlImageReader()
{
- quit = true;
- haveJob.wakeOne();
}
-void QmlImageReader::read(QmlPixmapReply *reply)
+QmlImageReader *QmlImageReader::instance(QmlEngine *engine)
+{
+ QmlImageReader *reader = readers.value(engine);
+ if (!reader) {
+ static QMutex rmutex;
+ rmutex.lock();
+ reader = new QmlImageReader(engine);
+ readers.insert(engine, reader);
+ rmutex.unlock();
+ }
+
+ return reader;
+}
+
+QmlPixmapReply *QmlImageReader::getImage(const QUrl &url)
{
mutex.lock();
- Job job;
- job.reply = reply;
- jobs.append(job);
+ QmlPixmapReply *reply = new QmlPixmapReply(engine, url);
+ jobs.append(reply);
if (jobs.count() == 1)
- haveJob.wakeOne();
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
mutex.unlock();
+ return reply;
}
void QmlImageReader::cancel(QmlPixmapReply *reply)
{
mutex.lock();
- QList<Job>::iterator it = jobs.begin();
- while (it != jobs.end()) {
- if ((*it).reply == reply) {
- jobs.erase(it);
- break;
+ if (reply->isLoading()) {
+ // Already requested. Add to cancel list to be cancelled in reader thread.
+ cancelled.append(reply);
+ if (cancelled.count() == 1)
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ } else {
+ // Not yet processed - just remove from waiting list
+ QList<QmlPixmapReply*>::iterator it = jobs.begin();
+ while (it != jobs.end()) {
+ QmlPixmapReply *job = *it;
+ if (job == reply) {
+ jobs.erase(it);
+ break;
+ }
+ ++it;
}
- ++it;
}
mutex.unlock();
}
-void QmlImageReader::loadImage(Job &job)
+void QmlImageReader::run()
{
- QImageReader imgio(job.reply->device());
- if (imgio.read(&job.img)) {
- job.error = false;
- } else {
- job.error = true;
- qWarning() << imgio.errorString();
+#ifdef Q_OS_LINUX
+ struct sched_param param;
+ int policy;
+
+ pthread_getschedparam(pthread_self(), &policy, &param);
+ pthread_setschedparam(pthread_self(), SCHED_IDLE, &param);
+#endif
+
+ exec();
+}
+
+bool QmlImageReader::event(QEvent *event)
+{
+ if (event->type() == QEvent::User) {
+ static int replyDownloadProgress = -1;
+ static int replyFinished = -1;
+ static int downloadProgress = -1;
+ static int thisNetworkRequestDone = -1;
+
+ if (replyDownloadProgress == -1) {
+ replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
+ replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()");
+ downloadProgress = QmlPixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
+ thisNetworkRequestDone = QmlImageReader::staticMetaObject.indexOfSlot("networkRequestDone()");
+ }
+
+ while (1) {
+ mutex.lock();
+
+ if (cancelled.count()) {
+ for (int i = 0; i < cancelled.count(); ++i) {
+ QmlPixmapReply *job = cancelled.at(i);
+ QNetworkReply *reply = replies.key(job, 0);
+ if (reply && reply->isRunning()) {
+ replies.remove(reply);
+ reply->close();
+ job->release(true);
+ }
+ }
+ cancelled.clear();
+ }
+
+ if (!accessManagerValid) {
+ // throw away existing requests and reschedule.
+ QHash<QNetworkReply*,QmlPixmapReply*>::iterator it = replies.begin();
+ for (; it != replies.end(); ++it) {
+ delete it.key();
+ jobs.prepend(*it);
+ }
+ replies.clear();
+ }
+
+ if (!jobs.count() || replies.count() > maxImageRequestCount) {
+ mutex.unlock();
+ break;
+ }
+
+ QmlPixmapReply *runningJob = jobs.takeFirst();
+ runningJob->addRef();
+ runningJob->setLoading();
+ QUrl url = runningJob->url();
+ mutex.unlock();
+
+ // fetch
+ QNetworkRequest req(url);
+ req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+ QNetworkReply *reply = networkAccessManager()->get(req);
+
+ QMetaObject::connect(reply, replyDownloadProgress, runningJob, downloadProgress);
+ QMetaObject::connect(reply, replyFinished, this, thisNetworkRequestDone);
+
+ replies.insert(reply, runningJob);
+ }
+ return true;
}
+
+ return QObject::event(event);
}
-void QmlImageReader::run()
+void QmlImageReader::networkRequestDone()
{
- while (1) {
- mutex.lock();
- if (!jobs.count())
- haveJob.wait(&mutex);
- if (quit)
- break;
- Job runningJob = jobs.takeFirst();
- runningJob.reply->addRef();
- mutex.unlock();
-
- loadImage(runningJob);
- QCoreApplication::postEvent(runningJob.reply, new QmlImageDecodeEvent(runningJob.error, runningJob.img));
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ QmlPixmapReply *job = replies.take(reply);
+ if (job) {
+ QImage image;
+ QmlImageReaderEvent::ReadError error;
+ if (reply->error()) {
+ error = QmlImageReaderEvent::Loading;
+ } else {
+ QImageReader imgio(reply);
+ if (imgio.read(&image)) {
+ error = QmlImageReaderEvent::NoError;
+ } else {
+ error = QmlImageReaderEvent::Decoding;
+ }
+ }
+ // send completion event to the QmlPixmapReply
+ QCoreApplication::postEvent(job, new QmlImageReaderEvent(error, image));
}
+ // kick off event loop again if we have dropped below max request count
+ if (replies.count() == maxImageRequestCount)
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ reply->deleteLater();
}
static bool readImage(QIODevice *dev, QPixmap *pixmap)
@@ -228,46 +364,26 @@ class QmlPixmapReplyPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QmlPixmapReply)
public:
- QmlPixmapReplyPrivate(const QUrl &u, QNetworkReply *r)
- : QObjectPrivate(), refCount(1), url(u), reply(r), status(QmlPixmapReply::Loading) {
+ QmlPixmapReplyPrivate(QmlEngine *e, const QUrl &u)
+ : QObjectPrivate(), refCount(1), url(u), status(QmlPixmapReply::Loading), loading(false), engine(e) {
}
int refCount;
QUrl url;
- QNetworkReply *reply;
QPixmap pixmap; // ensure reference to pixmap so QPixmapCache does not discard
- QImage image;
QmlPixmapReply::Status status;
+ bool loading;
+ QmlEngine *engine;
};
-QmlPixmapReply::QmlPixmapReply(const QUrl &url, QNetworkReply *reply)
- : QObject(*new QmlPixmapReplyPrivate(url, reply), 0)
+QmlPixmapReply::QmlPixmapReply(QmlEngine *engine, const QUrl &url)
+ : QObject(*new QmlPixmapReplyPrivate(engine, url), 0)
{
- Q_D(QmlPixmapReply);
-
- static int replyDownloadProgress = -1;
- static int replyFinished = -1;
- static int thisDownloadProgress = -1;
- static int thisNetworkRequestDone = -1;
-
- if (replyDownloadProgress == -1) {
- replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
- replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()");
- thisDownloadProgress = QmlPixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
- thisNetworkRequestDone = QmlPixmapReply::staticMetaObject.indexOfSlot("networkRequestDone()");
- }
-
- QMetaObject::connect(d->reply, replyDownloadProgress, this, thisDownloadProgress, Qt::DirectConnection);
- QMetaObject::connect(d->reply, replyFinished, this, thisNetworkRequestDone);
}
QmlPixmapReply::~QmlPixmapReply()
{
- Q_D(QmlPixmapReply);
- if (d->status == Decoding)
- qmlImageReader()->cancel(this);
- delete d->reply;
}
const QUrl &QmlPixmapReply::url() const
@@ -276,36 +392,16 @@ const QUrl &QmlPixmapReply::url() const
return d->url;
}
-void QmlPixmapReply::networkRequestDone()
-{
- Q_D(QmlPixmapReply);
- if (d->reply->error()) {
- d->pixmap = QPixmap();
- d->status = Error;
- QByteArray key = d->url.toEncoded(QUrl::FormattingOption(0x100));
- QString strKey = QString::fromLatin1(key.constData(), key.count());
- QPixmapCache::insert(strKey, d->pixmap);
- qWarning() << "Network error loading" << d->url << d->reply->errorString();
- emit finished();
- } else {
- qmlImageReader()->read(this);
- d->status = Decoding;
- }
-}
-
bool QmlPixmapReply::event(QEvent *event)
{
Q_D(QmlPixmapReply);
if (event->type() == QEvent::User) {
+ d->loading = false;
if (!release(true)) {
- QmlImageDecodeEvent *de = static_cast<QmlImageDecodeEvent*>(event);
- d->status = de->error ? Error : Ready;
- if (d->status == Ready) {
+ QmlImageReaderEvent *de = static_cast<QmlImageReaderEvent*>(event);
+ d->status = (de->error == QmlImageReaderEvent::NoError) ? Ready : Error;
+ if (d->status == Ready)
d->pixmap = QPixmap::fromImage(de->image);
- d->image = QImage();
- } else {
- qWarning() << "Error decoding" << d->url;
- }
QByteArray key = d->url.toEncoded(QUrl::FormattingOption(0x100));
QString strKey = QString::fromLatin1(key.constData(), key.count());
QPixmapCache::insert(strKey, d->pixmap);
@@ -323,10 +419,16 @@ QmlPixmapReply::Status QmlPixmapReply::status() const
return d->status;
}
-QIODevice *QmlPixmapReply::device()
+bool QmlPixmapReply::isLoading() const
+{
+ Q_D(const QmlPixmapReply);
+ return d->loading;
+}
+
+void QmlPixmapReply::setLoading()
{
Q_D(QmlPixmapReply);
- return d->reply;
+ d->loading = true;
}
void QmlPixmapReply::addRef()
@@ -342,11 +444,17 @@ bool QmlPixmapReply::release(bool defer)
--d->refCount;
if (d->refCount == 0) {
qmlActivePixmapReplies()->remove(d->url);
+ if (d->status == Loading && !d->loading)
+ QmlImageReader::instance(d->engine)->cancel(this);
if (defer)
deleteLater();
else
delete this;
return true;
+ } else if (d->refCount == 1 && d->loading) {
+ // The only reference left is the reader thread.
+ qmlActivePixmapReplies()->remove(d->url);
+ QmlImageReader::instance(d->engine)->cancel(this);
}
return false;
@@ -418,9 +526,8 @@ QmlPixmapReply *QmlPixmapCache::request(QmlEngine *engine, const QUrl &url)
{
QmlPixmapReplyHash::Iterator iter = qmlActivePixmapReplies()->find(url);
if (iter == qmlActivePixmapReplies()->end()) {
- QNetworkRequest req(url);
- req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
- QmlPixmapReply *item = new QmlPixmapReply(url, engine->networkAccessManager()->get(req));
+ QmlImageReader *reader = QmlImageReader::instance(engine);
+ QmlPixmapReply *item = reader->getImage(url);
iter = qmlActivePixmapReplies()->insert(url, item);
} else {
(*iter)->addRef();
diff --git a/src/declarative/util/qmlpixmapcache_p.h b/src/declarative/util/qmlpixmapcache_p.h
index 711e902..0140352 100644
--- a/src/declarative/util/qmlpixmapcache_p.h
+++ b/src/declarative/util/qmlpixmapcache_p.h
@@ -59,10 +59,10 @@ class Q_DECLARATIVE_EXPORT QmlPixmapReply : public QObject
{
Q_OBJECT
public:
- QmlPixmapReply(const QUrl &url, QNetworkReply *reply);
+ QmlPixmapReply(QmlEngine *engine, const QUrl &url);
~QmlPixmapReply();
- enum Status { Ready, Error, Unrequested, Loading, Decoding };
+ enum Status { Ready, Error, Unrequested, Loading };
Status status() const;
const QUrl &url() const;
@@ -75,12 +75,10 @@ protected:
bool event(QEvent *event);
private:
- QIODevice *device();
void addRef();
bool release(bool defer=false);
-
-private Q_SLOTS:
- void networkRequestDone();
+ bool isLoading() const;
+ void setLoading();
private:
Q_DISABLE_COPY(QmlPixmapReply)
diff --git a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
index ac0f73f..a36541e 100644
--- a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
+++ b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
@@ -129,6 +129,7 @@ void tst_QmlListModel::dynamic_data()
QTest::newRow("count") << "count" << 0 << "";
QTest::newRow("get1") << "{get(0)}" << 0 << "QML ListModel (unknown location) get: index 0 out of range";
+ QTest::newRow("get2") << "{get(-1)}" << 0 << "QML ListModel (unknown location) get: index -1 out of range";
QTest::newRow("append1") << "{append({'foo':123});count}" << 1 << "";
QTest::newRow("append2") << "{append({'foo':123,'bar':456});count}" << 1 << "";
@@ -146,6 +147,7 @@ void tst_QmlListModel::dynamic_data()
QTest::newRow("remove2b") << "{append({'foo':123});append({'foo':456});remove(0);get(0).foo}" << 456 << "";
QTest::newRow("remove2c") << "{append({'foo':123});append({'foo':456});remove(1);get(0).foo}" << 123 << "";
QTest::newRow("remove3") << "{append({'foo':123});remove(0);get(0).foo}" << 0 << "QML ListModel (unknown location) get: index 0 out of range";
+ QTest::newRow("remove3a") << "{append({'foo':123});remove(-1)}" << 0 << "QML ListModel (unknown location) remove: index -1 out of range";
QTest::newRow("remove4a") << "{remove(0)}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range";
QTest::newRow("remove4b") << "{append({'foo':123});remove(0);remove(0)}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range";
QTest::newRow("remove4c") << "{append({'foo':123});remove(1)}" << 0 << "QML ListModel (unknown location) remove: index 1 out of range";
@@ -166,6 +168,7 @@ void tst_QmlListModel::dynamic_data()
QTest::newRow("set3a") << "{append({'foo':123,'bar':456});set(0,{'foo':999});get(0).foo}" << 999 << "";
QTest::newRow("set3b") << "{append({'foo':123,'bar':456});set(0,{'foo':999});get(0).bar}" << 456 << "";
QTest::newRow("set4a") << "{set(0,{'foo':456})}" << 0 << "QML ListModel (unknown location) set: index 0 out of range";
+ QTest::newRow("set4c") << "{set(-1,{'foo':456})}" << 0 << "QML ListModel (unknown location) set: index -1 out of range";
QTest::newRow("set5a") << "{append({'foo':123,'bar':456});set(0,123)}" << 0 << "QML ListModel (unknown location) set: value is not an object";
QTest::newRow("set5b") << "{append({'foo':123,'bar':456});set(0,[1,2,3])}" << 0 << "QML ListModel (unknown location) set: value is not an object";
QTest::newRow("set6") << "{append({'foo':123});set(1,{'foo':456});count}" << 2 << "";
@@ -175,7 +178,8 @@ void tst_QmlListModel::dynamic_data()
QTest::newRow("setprop3a") << "{append({'foo':123,'bar':456});setProperty(0,'foo',999);get(0).foo}" << 999 << "";
QTest::newRow("setprop3b") << "{append({'foo':123,'bar':456});setProperty(0,'foo',999);get(0).bar}" << 456 << "";
QTest::newRow("setprop4a") << "{setProperty(0,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 0 out of range";
- QTest::newRow("setprop4a") << "{append({'foo':123,'bar':456});setProperty(1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 1 out of range";
+ QTest::newRow("setprop4b") << "{setProperty(-1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index -1 out of range";
+ QTest::newRow("setprop4c") << "{append({'foo':123,'bar':456});setProperty(1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 1 out of range";
QTest::newRow("setprop5") << "{append({'foo':123,'bar':456});append({'foo':111});setProperty(1,'bar',222);get(1).bar}" << 222 << "";
QTest::newRow("move1a") << "{append({'foo':123});append({'foo':456});move(0,1,1);count}" << 2 << "";
diff --git a/tests/benchmarks/declarative/declarative.pro b/tests/benchmarks/declarative/declarative.pro
index 2f85265..8433de5 100644
--- a/tests/benchmarks/declarative/declarative.pro
+++ b/tests/benchmarks/declarative/declarative.pro
@@ -6,7 +6,5 @@ SUBDIRS += \
qmlcomponent \
qmlgraphicsimage \
qmlmetaproperty \
- qmlpainting \
script \
- text
# qmltime
diff --git a/tests/benchmarks/declarative/qmlpainting/qmlpainting.pro b/tests/benchmarks/declarative/qmlpainting/qmlpainting.pro
deleted file mode 100644
index 971e18d..0000000
--- a/tests/benchmarks/declarative/qmlpainting/qmlpainting.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-load(qttest_p4)
-TEMPLATE = app
-TARGET = tst_qmlpainting
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qmlpainting.cpp
diff --git a/tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp b/tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp
deleted file mode 100644
index e14531f..0000000
--- a/tests/benchmarks/declarative/qmlpainting/tst_qmlpainting.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qtest.h>
-#include <QPainter>
-#include <QImage>
-
-#include <math.h>
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-class tst_QmlPainting : public QObject
-{
- Q_OBJECT
-
- public:
- tst_QmlPainting() {}
-
-private slots:
- void drawRoundedRect();
- void drawScaledRoundedRect();
- void drawTransformedRoundedRect();
-
- void drawAntialiasedRoundedRect();
- void drawScaledAntialiasedRoundedRect_data();
- void drawScaledAntialiasedRoundedRect();
- void drawTransformedAntialiasedRoundedRect_data();
- void drawTransformedAntialiasedRoundedRect();
-
- void drawImageRoundedRect();
- void drawScaledImageRoundedRect_data();
- void drawScaledImageRoundedRect();
- void drawTransformedImageRoundedRect_data();
- void drawTransformedImageRoundedRect();
-
- void drawScaleGridRoundedRect();
- void drawScaledScaleGridRoundedRect_data();
- void drawScaledScaleGridRoundedRect();
- void drawTransformedScaleGridRoundedRect_data();
- void drawTransformedScaleGridRoundedRect();
-
- void drawTransformedTransparentImage_data();
- void drawTransformedTransparentImage();
- void drawTransformedSemiTransparentImage_data();
- void drawTransformedSemiTransparentImage();
- void drawTransformedFilledImage_data();
- void drawTransformedFilledImage();
-};
-
-const qreal inv_dist_to_plane = 1. / 1024.;
-QTransform transformForAngle(qreal angle)
-{
- QTransform transform;
-
- QTransform rotTrans;
- rotTrans.translate(-40, 0);
- QTransform rotTrans2;
- rotTrans2.translate(40, 0);
-
- qreal rad = angle * 2. * M_PI / 360.;
- qreal c = ::cos(rad);
- qreal s = ::sin(rad);
-
- qreal x = 0;
- qreal y = 80;
- qreal z = 0;
-
- qreal len = x * x + y * y + z * z;
- if (len != 1.) {
- len = ::sqrt(len);
- x /= len;
- y /= len;
- z /= len;
- }
-
- QTransform rot(x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s*inv_dist_to_plane,
- y*x*(1-c)+z*s, y*y*(1-c)+c, y*z*(1-c)-x*s*inv_dist_to_plane,
- 0, 0, 1);
-
- transform *= rotTrans;
- transform *= rot;
- transform *= rotTrans2;
-
- return transform;
-}
-
-void tst_QmlPainting::drawRoundedRect()
-{
- QImage surface(100, 100, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- p.setPen(QPen(Qt::black, 1));
- p.setBrush(Qt::red);
-
- QBENCHMARK {
- p.drawRoundedRect(QRectF(.5, .5, 80, 80), 10, 10);
- }
- //surface.save("regular.png");
-}
-
-void tst_QmlPainting::drawScaledRoundedRect()
-{
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- p.setPen(QPen(Qt::black, 1));
- p.setBrush(Qt::red);
- p.scale(3, 3);
-
- QBENCHMARK {
- p.drawRoundedRect(10, 10, 80, 80, 10, 10);
- }
- //surface.save("scaled.png");
-}
-
-void tst_QmlPainting::drawTransformedRoundedRect()
-{
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- p.setPen(QPen(Qt::black, 1));
- p.setBrush(Qt::red);
-
- QBENCHMARK {
- p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
- p.drawRoundedRect(100, 100, 80, 80, 10, 10);
- }
- //surface.save("transformed.png");
-}
-
-void tst_QmlPainting::drawAntialiasedRoundedRect()
-{
- QImage surface(100, 100, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- p.setRenderHint(QPainter::Antialiasing, true);
- p.setPen(QPen(Qt::black, 1));
- p.setBrush(Qt::red);
-
- QBENCHMARK {
- p.drawRoundedRect(QRectF(.5, .5, 80, 80), 10, 10);
- }
- //surface.save("aar.png");
-}
-
-void tst_QmlPainting::drawScaledAntialiasedRoundedRect_data()
-{
- QTest::addColumn<float>("scale");
-
- for (float i = 0; i < 3; i += .1)
- QTest::newRow(QString(QLatin1String("scale=%1")).arg(i).toLatin1()) << i;
-}
-
-void tst_QmlPainting::drawScaledAntialiasedRoundedRect()
-{
- QFETCH(float, scale);
-
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- p.setRenderHint(QPainter::Antialiasing, true);
- p.setPen(QPen(Qt::black, 1));
- p.setBrush(Qt::red);
- p.scale(scale, scale);
-
- QBENCHMARK {
- p.drawRoundedRect(10, 10, 80, 80, 10, 10);
- }
- //surface.save("aas.png");
-}
-
-void tst_QmlPainting::drawTransformedAntialiasedRoundedRect_data()
-{
- QTest::addColumn<QTransform>("transform");
-
- for (float angle = 0; angle < 360; angle += 10)
- QTest::newRow(QString(QLatin1String("angle=%1")).arg(angle).toLatin1()) << transformForAngle(angle);
-}
-
-void tst_QmlPainting::drawTransformedAntialiasedRoundedRect()
-{
- QFETCH(QTransform, transform);
-
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- p.setRenderHint(QPainter::Antialiasing, true);
- p.setPen(QPen(Qt::black, 1));
- p.setBrush(Qt::red);
-
- QBENCHMARK {
- p.setWorldTransform(transform);
- p.drawRoundedRect(100, 100, 80, 80, 10, 10);
- }
- //surface.save("aat.png");
-}
-
-void tst_QmlPainting::drawImageRoundedRect()
-{
- //setup image
- const int radius = 10;
- QImage rectImage(81, 81, QImage::Format_ARGB32_Premultiplied);
- rectImage.fill(0);
- QPainter rp(&rectImage);
- rp.setRenderHint(QPainter::Antialiasing);
- rp.setPen(Qt::black);
- rp.setBrush(Qt::red);
- rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius);
-
- //setup surface
- QImage surface(100, 100, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- p.drawImage(0,0, rectImage);
- }
- //surface.save("ri.png");
-}
-
-void tst_QmlPainting::drawScaledImageRoundedRect_data()
-{
- QTest::addColumn<int>("imageType");
-
- QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
- QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
-}
-
-void tst_QmlPainting::drawScaledImageRoundedRect()
-{
- QFETCH(int, imageType);
-
- //setup image
- const int radius = 10;
- QImage rectImage(81, 81, (QImage::Format)imageType);
- rectImage.fill(0);
- QPainter rp(&rectImage);
- rp.setRenderHint(QPainter::Antialiasing);
- rp.setPen(Qt::black);
- rp.setBrush(Qt::red);
- rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius);
-
- //setup surface
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
- p.scale(3, 3);
-
- QBENCHMARK {
- p.drawImage(0,0, rectImage);
- }
- //surface.save("si.png");
-}
-
-void tst_QmlPainting::drawTransformedImageRoundedRect_data()
-{
- QTest::addColumn<int>("imageType");
-
- QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
- QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
-}
-
-void tst_QmlPainting::drawTransformedImageRoundedRect()
-{
- QFETCH(int, imageType);
-
- //setup image
- const int radius = 10;
- QImage rectImage(81, 81, (QImage::Format)imageType);
- rectImage.fill(0);
- QPainter rp(&rectImage);
- rp.setRenderHint(QPainter::Antialiasing);
- rp.setPen(Qt::black);
- rp.setBrush(Qt::red);
- rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius);
-
- //setup surface
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
- p.drawImage(100,100, rectImage);
- }
- //surface.save("ti.png");
-}
-
-//code from QmlGraphicsRectangle for drawing rounded rects
-void tst_QmlPainting::drawScaleGridRoundedRect()
-{
- //setup image
- const int pw = 1;
- const int radius = 10;
- QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, QImage::Format_ARGB32_Premultiplied);
- rectImage.fill(0);
- QPainter rp(&rectImage);
- rp.setRenderHint(QPainter::Antialiasing);
- rp.setPen(Qt::black);
- rp.setBrush(Qt::red);
- if (pw%2)
- rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius);
- else
- rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius);
- QPixmap rectPixmap = QPixmap::fromImage(rectImage);
-
- //setup surface
- QImage surface(100, 100, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- const int pw = 2;
- int width = 80;
- int height = 80;
-
- int xOffset = (rectPixmap.width()-1)/2;
- int yOffset = (rectPixmap.height()-1)/2;
- Q_ASSERT(rectPixmap.width() == 2*xOffset + 1);
- Q_ASSERT(rectPixmap.height() == 2*yOffset + 1);
-
- QMargins margins(xOffset, yOffset, xOffset, yOffset);
- QTileRules rules(Qt::StretchTile, Qt::StretchTile);
- //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects
- qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules);
- }
- //surface.save("rsg.png");
-}
-
-void tst_QmlPainting::drawScaledScaleGridRoundedRect_data()
-{
- QTest::addColumn<float>("scale");
- QTest::addColumn<int>("imageType");
-
- for (float i = 0; i < 3; i += .1)
- QTest::newRow(QString(QLatin1String("scale=%1; imagetype=ARGB32_Pre")).arg(i).toLatin1()) << i << (int)QImage::Format_ARGB32_Premultiplied;
- //for (float i = 0; i < 3; i += .1)
- // QTest::newRow(QString(QLatin1String("scale=%1; imagetype=ARGB8565_Pre")).arg(i).toLatin1()) << i << (int)QImage::Format_ARGB8565_Premultiplied;
-}
-
-//code from QmlGraphicsRectangle for drawing rounded rects
-void tst_QmlPainting::drawScaledScaleGridRoundedRect()
-{
- QFETCH(float, scale);
- QFETCH(int, imageType);
-
- //setup image
- const int pw = 1;
- const int radius = 10;
- QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, (QImage::Format)imageType);
- rectImage.fill(0);
- QPainter rp(&rectImage);
- rp.setRenderHint(QPainter::Antialiasing);
- rp.setPen(Qt::black);
- rp.setBrush(Qt::red);
- if (pw%2)
- rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius);
- else
- rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius);
-
- QPixmap rectPixmap = QPixmap::fromImage(rectImage);
-
- //setup surface
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
- p.scale(scale, scale);
-
- QBENCHMARK {
- const int pw = 2;
- int width = 80;
- int height = 80;
-
- int xOffset = (rectPixmap.width()-1)/2;
- int yOffset = (rectPixmap.height()-1)/2;
- Q_ASSERT(rectPixmap.width() == 2*xOffset + 1);
- Q_ASSERT(rectPixmap.height() == 2*yOffset + 1);
-
- QMargins margins(xOffset, yOffset, xOffset, yOffset);
- QTileRules rules(Qt::StretchTile, Qt::StretchTile);
- //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects
- qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules);
- }
- //surface.save("ssg.png");
-}
-
-void tst_QmlPainting::drawTransformedScaleGridRoundedRect_data()
-{
- QTest::addColumn<QTransform>("transform");
- QTest::addColumn<int>("imageType");
-
- for (float angle = 0; angle < 360; angle += 10)
- QTest::newRow(QString(QLatin1String("angle=%1; imagetype=ARGB32_Pre")).arg(angle).toLatin1()) << transformForAngle(angle) << (int)QImage::Format_ARGB32_Premultiplied;
- //for (float angle = 0; angle < 360; angle += 10)
- // QTest::newRow(QString(QLatin1String("angle=%1; imagetype=ARGB8565_Pre")).arg(angle).toLatin1()) << transformForAngle(angle) << (int)QImage::Format_ARGB8565_Premultiplied;
-
-}
-
-//code from QmlGraphicsRectangle for drawing rounded rects
-void tst_QmlPainting::drawTransformedScaleGridRoundedRect()
-{
- QFETCH(QTransform, transform);
- QFETCH(int, imageType);
-
- //setup image
- const int pw = 1;
- const int radius = 10;
- QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, (QImage::Format)imageType);
- rectImage.fill(0);
- QPainter rp(&rectImage);
- rp.setRenderHint(QPainter::Antialiasing);
- rp.setPen(Qt::black);
- rp.setBrush(Qt::red);
- if (pw%2)
- rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius);
- else
- rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius);
-
- QPixmap rectPixmap = QPixmap::fromImage(rectImage);
-
- //setup surface
- QImage surface(400, 400, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- p.setWorldTransform(transform);
- const int pw = 2;
- //int offset = int(radius+1.5+pw);
- int width = 80;
- int height = 80;
-
- int xOffset = (rectPixmap.width()-1)/2;
- int yOffset = (rectPixmap.height()-1)/2;
- Q_ASSERT(rectPixmap.width() == 2*xOffset + 1);
- Q_ASSERT(rectPixmap.height() == 2*yOffset + 1);
-
- QMargins margins(xOffset, yOffset, xOffset, yOffset);
- QTileRules rules(Qt::StretchTile, Qt::StretchTile);
- //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects
- qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules);
- }
- //surface.save("tsg.png");
-}
-
-void tst_QmlPainting::drawTransformedTransparentImage_data()
-{
- QTest::addColumn<int>("imageType");
-
- QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
- QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
-}
-
-void tst_QmlPainting::drawTransformedTransparentImage()
-{
- QFETCH(int, imageType);
-
- //setup image
- QImage transImage(200, 200, (QImage::Format)imageType);
- transImage.fill(0);
-
- //setup surface
- QImage surface(200, 200, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
- p.drawImage(0,0, transImage);
- }
-}
-
-void tst_QmlPainting::drawTransformedSemiTransparentImage_data()
-{
- QTest::addColumn<int>("imageType");
-
- QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
- QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
-}
-
-void tst_QmlPainting::drawTransformedSemiTransparentImage()
-{
- QFETCH(int, imageType);
-
- //setup image
- QImage transImage(200, 200, (QImage::Format)imageType);
- transImage.fill(QColor(0,0,0, 128).rgba());
-
- //setup surface
- QImage surface(200, 200, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
- p.drawImage(0,0, transImage);
- }
-}
-
-void tst_QmlPainting::drawTransformedFilledImage_data()
-{
- QTest::addColumn<int>("imageType");
-
- QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
- QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
-}
-
-void tst_QmlPainting::drawTransformedFilledImage()
-{
- QFETCH(int, imageType);
-
- //setup image
- QImage filledImage(200, 200, (QImage::Format)imageType);
- filledImage.fill(QColor(0,0,0).rgb());
-
- //setup surface
- QImage surface(200, 200, QImage::Format_RGB16);
- surface.fill(QColor(255,255,255).rgb());
- QPainter p(&surface);
-
- QBENCHMARK {
- p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
- p.drawImage(0,0, filledImage);
- }
-}
-
-QTEST_MAIN(tst_QmlPainting)
-
-#include "tst_qmlpainting.moc"
diff --git a/tests/benchmarks/declarative/signalemission/signalemission.pro b/tests/benchmarks/declarative/signalemission/signalemission.pro
deleted file mode 100644
index 0119aff..0000000
--- a/tests/benchmarks/declarative/signalemission/signalemission.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-load(qttest_p4)
-TEMPLATE = app
-TARGET = tst_signalemission
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_signalemission.cpp
-
diff --git a/tests/benchmarks/declarative/signalemission/tst_signalemission.cpp b/tests/benchmarks/declarative/signalemission/tst_signalemission.cpp
deleted file mode 100644
index 8327638..0000000
--- a/tests/benchmarks/declarative/signalemission/tst_signalemission.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qtest.h>
-#include <QObject>
-#include <QDebug>
-
-class LotsOfSignals : public QObject
-{
- Q_OBJECT
-public:
- LotsOfSignals() {}
-
-signals:
- void extraSignal1();
- void extraSignal2();
- void extraSignal3();
- void extraSignal4();
- void extraSignal5();
- void extraSignal6();
- void extraSignal7();
- void extraSignal8();
- void extraSignal9();
- void extraSignal10();
- void extraSignal12();
- void extraSignal13();
- void extraSignal14();
- void extraSignal15();
- void extraSignal16();
- void extraSignal17();
- void extraSignal18();
- void extraSignal19();
- void extraSignal20();
- void extraSignal21();
- void extraSignal22();
- void extraSignal23();
- void extraSignal24();
- void extraSignal25();
- void extraSignal26();
- void extraSignal27();
- void extraSignal28();
- void extraSignal29();
- void extraSignal30();
- void extraSignal31();
- void extraSignal32();
- void extraSignal33();
- void extraSignal34();
- void extraSignal35();
- void extraSignal36();
- void extraSignal37();
- void extraSignal38();
- void extraSignal39();
- void extraSignal40();
- void extraSignal41();
- void extraSignal42();
- void extraSignal43();
- void extraSignal44();
- void extraSignal45();
- void extraSignal46();
- void extraSignal47();
- void extraSignal48();
- void extraSignal49();
- void extraSignal50();
- void extraSignal51();
- void extraSignal52();
- void extraSignal53();
- void extraSignal54();
- void extraSignal55();
- void extraSignal56();
- void extraSignal57();
- void extraSignal58();
- void extraSignal59();
- void extraSignal60();
- void extraSignal61();
- void extraSignal62();
- void extraSignal63();
- void extraSignal64();
- void extraSignal65();
- void extraSignal66();
- void extraSignal67();
- void extraSignal68();
- void extraSignal69();
- void extraSignal70();
-};
-
-class tst_signalemission : public QObject
-{
- Q_OBJECT
-public:
- tst_signalemission() {}
-
-private slots:
- void unconnected_data();
- void unconnected();
-};
-
-void tst_signalemission::unconnected_data()
-{
- QTest::addColumn<int>("signal_index");
- QTest::newRow("9") << 9;
- QTest::newRow("32") << 32;
- QTest::newRow("33") << 33;
- QTest::newRow("64") << 64;
- QTest::newRow("65") << 65;
- QTest::newRow("70") << 70;
-}
-
-void tst_signalemission::unconnected()
-{
- LotsOfSignals *obj = new LotsOfSignals;
- QFETCH(int, signal_index);
- QVERIFY(obj->metaObject()->methodCount() == 73);
- void *v;
- QBENCHMARK {
- //+1 because QObject has one slot
- QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, signal_index+1, &v);
- }
- delete obj;
-}
-
-QTEST_MAIN(tst_signalemission)
-#include "tst_signalemission.moc"
diff --git a/tests/benchmarks/declarative/text/text.pro b/tests/benchmarks/declarative/text/text.pro
deleted file mode 100644
index 3320f53..0000000
--- a/tests/benchmarks/declarative/text/text.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-load(qttest_p4)
-TEMPLATE = app
-TARGET = tst_text
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_text.cpp
-
diff --git a/tests/benchmarks/declarative/text/tst_text.cpp b/tests/benchmarks/declarative/text/tst_text.cpp
deleted file mode 100644
index 33ee237..0000000
--- a/tests/benchmarks/declarative/text/tst_text.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qtest.h>
-#include <QTextLayout>
-#include <QPainter>
-#include <QSize>
-#include <qmath.h>
-#include <private/qtextcontrol_p.h>
-
-class tst_text : public QObject
-{
- Q_OBJECT
-public:
- tst_text()
- {
- m_text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
- }
-
-private slots:
- void layout();
- void paintLayoutToPixmap();
- void paintLayoutToPixmap_painterFill();
- void document();
- void paintDocToPixmap();
- void paintDocToPixmap_painterFill();
- void control();
- void paintControlToPixmap();
- void paintControlToPixmap_painterFill();
- void constructControl();
- void constructDocument();
-
-private:
- QString m_text;
-};
-
-QSize setupTextLayout(QTextLayout *layout)
-{
- bool wrap = true;
- int wrapWidth = 300;
- layout->setCacheEnabled(true);
-
- int height = 0;
- qreal widthUsed = 0;
- qreal lineWidth = 0;
-
- //set manual width
- if (wrap)
- lineWidth = wrapWidth;
-
- layout->beginLayout();
-
- while (1) {
- QTextLine line = layout->createLine();
- if (!line.isValid())
- break;
-
- if (wrap)
- line.setLineWidth(lineWidth);
- }
- layout->endLayout();
-
- for (int i = 0; i < layout->lineCount(); ++i) {
- QTextLine line = layout->lineAt(i);
- widthUsed = qMax(widthUsed, line.naturalTextWidth());
- line.setPosition(QPointF(0, height));
- height += int(line.height());
- }
- return QSize(qCeil(widthUsed), height);
-}
-
-void tst_text::layout()
-{
- //get rid of initialization effects
- QTextLayout layout(m_text);
- setupTextLayout(&layout);
-
- QBENCHMARK {
- QTextLayout layout(m_text);
- setupTextLayout(&layout);
- }
-}
-
-void tst_text::paintLayoutToPixmap()
-{
- QTextLayout layout(m_text);
- QSize size = setupTextLayout(&layout);
-
- QBENCHMARK {
- QPixmap img(size);
- img.fill(Qt::transparent);
- QPainter p(&img);
- layout.draw(&p, QPointF(0, 0));
- }
-}
-
-void tst_text::paintLayoutToPixmap_painterFill()
-{
- QTextLayout layout(m_text);
- QSize size = setupTextLayout(&layout);
-
- QBENCHMARK {
- QPixmap img(size);
- QPainter p(&img);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(0, 0, img.width(), img.height(), Qt::transparent);
- p.setCompositionMode(QPainter::CompositionMode_SourceOver);
- layout.draw(&p, QPointF(0, 0));
- }
-}
-
-void tst_text::document()
-{
- QTextDocument *doc = new QTextDocument;
-
- QBENCHMARK {
- QTextDocument *doc = new QTextDocument;
- doc->setHtml(m_text);
- }
-}
-
-void tst_text::paintDocToPixmap()
-{
- QTextDocument *doc = new QTextDocument;
- doc->setHtml(m_text);
- doc->setTextWidth(300);
- QSize size = doc->size().toSize();
-
- QBENCHMARK {
- QPixmap img(size);
- img.fill(Qt::transparent);
- QPainter p(&img);
- doc->drawContents(&p);
- }
-}
-
-void tst_text::paintDocToPixmap_painterFill()
-{
- QTextDocument *doc = new QTextDocument;
- doc->setHtml(m_text);
- doc->setTextWidth(300);
- QSize size = doc->size().toSize();
-
- QBENCHMARK {
- QPixmap img(size);
- QPainter p(&img);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(0, 0, img.width(), img.height(), Qt::transparent);
- p.setCompositionMode(QPainter::CompositionMode_SourceOver);
- doc->drawContents(&p);
- }
-}
-
-void tst_text::control()
-{
- QTextControl *control = new QTextControl(m_text);
-
- QBENCHMARK {
- QTextControl *control = new QTextControl;
- QTextDocument *doc = control->document();
- doc->setHtml(m_text);
- }
-}
-
-void tst_text::paintControlToPixmap()
-{
- QTextControl *control = new QTextControl;
- QTextDocument *doc = control->document();
- doc->setHtml(m_text);
- doc->setTextWidth(300);
- QSize size = doc->size().toSize();
-
- QBENCHMARK {
- QPixmap img(size);
- img.fill(Qt::transparent);
- QPainter p(&img);
- control->drawContents(&p, QRectF(QPointF(0, 0), QSizeF(size)));
- }
-}
-
-void tst_text::paintControlToPixmap_painterFill()
-{
- QTextControl *control = new QTextControl;
- QTextDocument *doc = control->document();
- doc->setHtml(m_text);
- doc->setTextWidth(300);
- QSize size = doc->size().toSize();
-
- QBENCHMARK {
- QPixmap img(size);
- QPainter p(&img);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(0, 0, img.width(), img.height(), Qt::transparent);
- p.setCompositionMode(QPainter::CompositionMode_SourceOver);
- control->drawContents(&p, QRectF(QPointF(0, 0), QSizeF(size)));
- }
-}
-
-void tst_text::constructControl()
-{
- QTextControl *control = new QTextControl;
- delete control;
-
- QBENCHMARK {
- QTextControl *control = new QTextControl;
- delete control;
- }
-}
-
-void tst_text::constructDocument()
-{
- QTextDocument *doc = new QTextDocument;
- delete doc;
-
- QBENCHMARK {
- QTextDocument *doc = new QTextDocument;
- delete doc;
- }
-}
-
-QTEST_MAIN(tst_text)
-#include "tst_text.moc"
diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp
index 7dfecc8..71ba81c 100644
--- a/tools/qmlviewer/qmlviewer.cpp
+++ b/tools/qmlviewer/qmlviewer.cpp
@@ -45,6 +45,7 @@
#include "qmlviewer.h"
#include <qmlcontext.h>
#include <qmlengine.h>
+#include <qmlnetworkaccessmanagerfactory.h>
#include "qml.h"
#include <private/qperformancelog_p_p.h>
#include <private/qabstractanimation_p.h>
@@ -80,6 +81,8 @@
#include <QTimer>
#include <QNetworkProxyFactory>
#include <QKeyEvent>
+#include <QMutex>
+#include <QMutexLocker>
#include "proxysettings.h"
#include "deviceorientation.h"
@@ -298,9 +301,22 @@ public:
PersistentCookieJar(QObject *parent) : QNetworkCookieJar(parent) { load(); }
~PersistentCookieJar() { save(); }
+ virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const
+ {
+ QMutexLocker lock(&mutex);
+ return QNetworkCookieJar::cookiesForUrl(url);
+ }
+
+ virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
+ {
+ QMutexLocker lock(&mutex);
+ return QNetworkCookieJar::setCookiesFromUrl(cookieList, url);
+ }
+
private:
void save()
{
+ QMutexLocker lock(&mutex);
QList<QNetworkCookie> list = allCookies();
QByteArray data;
foreach (QNetworkCookie cookie, list) {
@@ -315,12 +331,90 @@ private:
void load()
{
+ QMutexLocker lock(&mutex);
QSettings settings("Nokia", "QtQmlViewer");
QByteArray data = settings.value("Cookies").toByteArray();
setAllCookies(QNetworkCookie::parseCookies(data));
}
+
+ mutable QMutex mutex;
};
+class NetworkAccessManagerFactory : public QmlNetworkAccessManagerFactory
+{
+public:
+ NetworkAccessManagerFactory() : cookieJar(0), cacheSize(0) {}
+
+ QNetworkAccessManager *create(QObject *parent) {
+ QMutexLocker lock(&mutex);
+ QNetworkAccessManager *manager = new QNetworkAccessManager(parent);
+ if (!cookieJar)
+ cookieJar = new PersistentCookieJar(this);
+ manager->setCookieJar(cookieJar);
+ cookieJar->setParent(this);
+ setupProxy(manager);
+ if (cacheSize > 0) {
+ QNetworkDiskCache *cache = new QNetworkDiskCache;
+ cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-duiviewer-network-cache"));
+ cache->setMaximumCacheSize(cacheSize);
+ manager->setCache(cache);
+ } else {
+ manager->setCache(0);
+ }
+ qDebug() << "created new manager for" << parent;
+ return manager;
+ }
+
+ void setupProxy(QNetworkAccessManager *nam)
+ {
+ class SystemProxyFactory : public QNetworkProxyFactory
+ {
+ public:
+ virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query)
+ {
+ QString protocolTag = query.protocolTag();
+ if (httpProxyInUse && (protocolTag == "http" || protocolTag == "https")) {
+ QList<QNetworkProxy> ret;
+ ret << httpProxy;
+ return ret;
+ }
+ return QNetworkProxyFactory::systemProxyForQuery(query);
+ }
+ void setHttpProxy (QNetworkProxy proxy)
+ {
+ httpProxy = proxy;
+ httpProxyInUse = true;
+ }
+ void unsetHttpProxy ()
+ {
+ httpProxyInUse = false;
+ }
+ private:
+ bool httpProxyInUse;
+ QNetworkProxy httpProxy;
+ };
+
+ SystemProxyFactory *proxyFactory = new SystemProxyFactory;
+ if (ProxySettings::httpProxyInUse())
+ proxyFactory->setHttpProxy(ProxySettings::httpProxy());
+ else
+ proxyFactory->unsetHttpProxy();
+ nam->setProxyFactory(proxyFactory);
+ }
+
+ void setCacheSize(int size) {
+ if (size != cacheSize) {
+ cacheSize = size;
+ invalidate();
+ }
+ }
+
+ PersistentCookieJar *cookieJar;
+ QMutex mutex;
+ int cacheSize;
+};
+
+
QString QmlViewer::getVideoFileName()
{
QString title = convertAvailable || ffmpegAvailable ? tr("Save Video File") : tr("Save PNG Frames");
@@ -397,8 +491,8 @@ QmlViewer::QmlViewer(QWidget *parent, Qt::WindowFlags flags)
setCentralWidget(canvas);
#endif
- setupProxy();
- canvas->engine()->networkAccessManager()->setCookieJar(new PersistentCookieJar(this));
+ namFactory = new NetworkAccessManagerFactory;
+ canvas->engine()->setNetworkAccessManagerFactory(namFactory);
connect(&autoStartTimer, SIGNAL(triggered()), this, SLOT(autoStartRecording()));
connect(&autoStopTimer, SIGNAL(triggered()), this, SLOT(autoStopRecording()));
@@ -409,6 +503,12 @@ QmlViewer::QmlViewer(QWidget *parent, Qt::WindowFlags flags)
recordTimer.setRepeating(true);
}
+QmlViewer::~QmlViewer()
+{
+ canvas->engine()->setNetworkAccessManagerFactory(0);
+ delete namFactory;
+}
+
void QmlViewer::adjustSizeSlot()
{
resize(sizeHint());
@@ -591,7 +691,7 @@ void QmlViewer::showProxySettings()
void QmlViewer::proxySettingsChanged()
{
- setupProxy ();
+ namFactory->invalidate();
reload ();
}
@@ -1325,63 +1425,9 @@ void QmlViewer::setDeviceKeys(bool on)
devicemode = on;
}
-void QmlViewer::setupProxy()
-{
- class SystemProxyFactory : public QNetworkProxyFactory
- {
- public:
- virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query)
- {
- QString protocolTag = query.protocolTag();
- if (httpProxyInUse && (protocolTag == "http" || protocolTag == "https")) {
- QList<QNetworkProxy> ret;
- ret << httpProxy;
- return ret;
- }
- return QNetworkProxyFactory::systemProxyForQuery(query);
- }
- void setHttpProxy (QNetworkProxy proxy)
- {
- httpProxy = proxy;
- httpProxyInUse = true;
- }
- void unsetHttpProxy ()
- {
- httpProxyInUse = false;
- }
- private:
- bool httpProxyInUse;
- QNetworkProxy httpProxy;
- };
-
- QNetworkAccessManager * nam = canvas->engine()->networkAccessManager();
- SystemProxyFactory *proxyFactory = new SystemProxyFactory;
- if (ProxySettings::httpProxyInUse())
- proxyFactory->setHttpProxy(ProxySettings::httpProxy());
- else
- proxyFactory->unsetHttpProxy();
- nam->setProxyFactory(proxyFactory);
-}
-
void QmlViewer::setNetworkCacheSize(int size)
{
- QNetworkAccessManager * nam = canvas->engine()->networkAccessManager();
- QNetworkDiskCache *cache = qobject_cast<QNetworkDiskCache*>(nam->cache());
- if (!cache) {
- if (size==0)
- return;
- cache = new QNetworkDiskCache;
- cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-duiviewer-network-cache"));
- nam->setCache(cache);
- }
- if (size == cache->maximumCacheSize())
- return;
- if (size>0) {
- // Setup a caching network manager
- cache->setMaximumCacheSize(size);
- } else {
- nam->setCache(0);
- }
+ namFactory->setCacheSize(size);
}
void QmlViewer::setUseGL(bool useGL)
diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h
index 3b14d39..6b05584 100644
--- a/tools/qmlviewer/qmlviewer.h
+++ b/tools/qmlviewer/qmlviewer.h
@@ -57,6 +57,8 @@ class QProcess;
class RecordingDialog;
class QmlGraphicsTester;
class QNetworkReply;
+class QNetworkCookieJar;
+class NetworkAccessManagerFactory;
class QmlViewer
#if defined(Q_OS_SYMBIAN)
@@ -68,6 +70,7 @@ class QmlViewer
Q_OBJECT
public:
QmlViewer(QWidget *parent=0, Qt::WindowFlags flags=0);
+ ~QmlViewer();
enum ScriptOption {
Play = 0x00000001,
@@ -138,7 +141,6 @@ private slots:
void unpackWgt();
private:
- void setupProxy();
QString getVideoFileName();
PreviewDeviceSkin *skin;
@@ -181,6 +183,8 @@ private:
QNetworkReply *wgtreply;
QString wgtdir;
+ NetworkAccessManagerFactory *namFactory;
+
bool useQmlFileBrowser;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QmlViewer::ScriptOptions)