summaryrefslogtreecommitdiffstats
path: root/src/declarative/util
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@nokia.com>2010-07-13 09:33:02 (GMT)
committerMartin Smith <martin.smith@nokia.com>2010-07-13 09:33:02 (GMT)
commite305732c0df93332a514a957b08e0ce283cb747f (patch)
tree603522227e5d4e9f2994408afd5d5523951ba648 /src/declarative/util
parentc93c9bbfe94cd271aeda9e2730d343e3eee31ec5 (diff)
parenta296749eaea94ae4ed36086b632d32c87d3d99c9 (diff)
downloadQt-e305732c0df93332a514a957b08e0ce283cb747f.zip
Qt-e305732c0df93332a514a957b08e0ce283cb747f.tar.gz
Qt-e305732c0df93332a514a957b08e0ce283cb747f.tar.bz2
Fixing merge conflicts.
Merge branch '4.7-upstream' into 4.7 Conflicts: doc/src/declarative/advtutorial.qdoc src/declarative/graphicsitems/qdeclarativeloader.cpp src/declarative/graphicsitems/qdeclarativetextedit.cpp src/declarative/qml/qdeclarativeengine.cpp src/declarative/util/qdeclarativexmllistmodel.cpp
Diffstat (limited to 'src/declarative/util')
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp10
-rw-r--r--src/declarative/util/qdeclarativeanimation_p.h5
-rw-r--r--src/declarative/util/qdeclarativebehavior.cpp23
-rw-r--r--src/declarative/util/qdeclarativebehavior_p.h2
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp2
-rw-r--r--src/declarative/util/qdeclarativepackage.cpp4
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp1175
-rw-r--r--src/declarative/util/qdeclarativepixmapcache_p.h85
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation.cpp2
-rw-r--r--src/declarative/util/qdeclarativesmoothedfollow.cpp299
-rw-r--r--src/declarative/util/qdeclarativesmoothedfollow_p.h113
-rw-r--r--src/declarative/util/qdeclarativespringanimation.cpp (renamed from src/declarative/util/qdeclarativespringfollow.cpp)292
-rw-r--r--src/declarative/util/qdeclarativespringanimation_p.h (renamed from src/declarative/util/qdeclarativespringfollow_p.h)42
-rw-r--r--src/declarative/util/qdeclarativestyledtext.cpp6
-rw-r--r--src/declarative/util/qdeclarativeutilmodule.cpp6
-rw-r--r--src/declarative/util/qdeclarativeview.cpp47
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp4
-rw-r--r--src/declarative/util/util.pri6
18 files changed, 1021 insertions, 1102 deletions
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index add27f3..bdb9510 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -142,6 +142,16 @@ bool QDeclarativeAbstractAnimation::isRunning() const
return d->running;
}
+// the behavior calls this function
+void QDeclarativeAbstractAnimation::notifyRunningChanged(bool running)
+{
+ Q_D(QDeclarativeAbstractAnimation);
+ if (d->disableUserControl && d->running != running) {
+ d->running = running;
+ emit runningChanged(running);
+ }
+}
+
//commence is called to start an animation when it is used as a
//simple animation, and not as part of a transition
void QDeclarativeAbstractAnimationPrivate::commence()
diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h
index 3f8fbdd..59bd465 100644
--- a/src/declarative/util/qdeclarativeanimation_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p.h
@@ -134,9 +134,12 @@ public:
private Q_SLOTS:
void timelineComplete();
void componentFinalized();
-
private:
virtual void setTarget(const QDeclarativeProperty &);
+ void notifyRunningChanged(bool running);
+ friend class QDeclarativeBehavior;
+
+
};
class QDeclarativePauseAnimationPrivate;
diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp
index 047993e..2bb28c3 100644
--- a/src/declarative/util/qdeclarativebehavior.cpp
+++ b/src/declarative/util/qdeclarativebehavior.cpp
@@ -58,7 +58,8 @@ class QDeclarativeBehaviorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QDeclarativeBehavior)
public:
- QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false) {}
+ QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false)
+ , blockRunningChanged(false) {}
QDeclarativeProperty property;
QVariant currentValue;
@@ -66,6 +67,7 @@ public:
QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
bool enabled;
bool finalized;
+ bool blockRunningChanged;
};
/*!
@@ -132,9 +134,22 @@ void QDeclarativeBehavior::setAnimation(QDeclarativeAbstractAnimation *animation
if (d->animation) {
d->animation->setDefaultTarget(d->property);
d->animation->setDisableUserControl();
+ connect(d->animation->qtAnimation(),
+ SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
+ this,
+ SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
}
}
+
+void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
+{
+ Q_D(QDeclarativeBehavior);
+ if (!d->blockRunningChanged)
+ d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
+}
+
+
/*!
\qmlproperty bool Behavior::enabled
Whether the Behavior will be triggered when the property it is tracking changes.
@@ -173,8 +188,11 @@ void QDeclarativeBehavior::write(const QVariant &value)
d->currentValue = d->property.read();
d->targetValue = value;
- if (d->animation->qtAnimation()->duration() != -1)
+ if (d->animation->qtAnimation()->duration() != -1
+ && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
+ d->blockRunningChanged = true;
d->animation->qtAnimation()->stop();
+ }
QDeclarativeStateOperation::ActionList actions;
QDeclarativeAction action;
@@ -186,6 +204,7 @@ void QDeclarativeBehavior::write(const QVariant &value)
QList<QDeclarativeProperty> after;
d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
d->animation->qtAnimation()->start();
+ d->blockRunningChanged = false;
if (!after.contains(d->property))
QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
}
diff --git a/src/declarative/util/qdeclarativebehavior_p.h b/src/declarative/util/qdeclarativebehavior_p.h
index 6c10eec..9801fb2 100644
--- a/src/declarative/util/qdeclarativebehavior_p.h
+++ b/src/declarative/util/qdeclarativebehavior_p.h
@@ -47,6 +47,7 @@
#include <qdeclarativepropertyvaluesource.h>
#include <qdeclarativepropertyvalueinterceptor.h>
#include <qdeclarative.h>
+#include <QtCore/QAbstractAnimation>
QT_BEGIN_HEADER
@@ -85,6 +86,7 @@ Q_SIGNALS:
private Q_SLOTS:
void componentFinalized();
+ void qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State);
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index deb835d..3ede335 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -1022,6 +1022,8 @@ QVariant NestedListModel::data(int index, int role) const
Q_ASSERT(_root && index >= 0 && index < _root->values.count());
checkRoles();
QVariant rv;
+ if (roleStrings.count() < role)
+ return rv;
ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
if (!node)
diff --git a/src/declarative/util/qdeclarativepackage.cpp b/src/declarative/util/qdeclarativepackage.cpp
index 1e49ad9..1a4f2a7 100644
--- a/src/declarative/util/qdeclarativepackage.cpp
+++ b/src/declarative/util/qdeclarativepackage.cpp
@@ -65,12 +65,12 @@ QT_BEGIN_NAMESPACE
\snippet examples/declarative/modelviews/package/Delegate.qml 0
These named items are used as the delegates by the two views who
- reference the special VisualDataModel.parts property to select
+ reference the special \l{VisualDataModel::parts} property to select
a model which provides the chosen delegate.
\snippet examples/declarative/modelviews/package/view.qml 0
- \sa {declarative/modelviews/package}{Package example}, QtDeclarative
+ \sa {declarative/modelviews/package}{Package example}, {demos/declarative/photoviewer}{Photo Viewer demo}, QtDeclarative
*/
/*!
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index 0c2f23d..00dd922 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -55,104 +55,209 @@
#include <QFile>
#include <QThread>
#include <QMutex>
+#include <QMutexLocker>
+#include <QWaitCondition>
#include <QBuffer>
#include <QWaitCondition>
#include <QtCore/qdebug.h>
#include <private/qobject_p.h>
#include <QSslError>
-// Maximum number of simultaneous image requests to send.
-static const int maxImageRequestCount = 8;
+#define IMAGEREQUEST_MAX_REQUEST_COUNT 8
+#define IMAGEREQUEST_MAX_REDIRECT_RECURSION 16
+#define CACHE_EXPIRE_TIME 30
+#define CACHE_REMOVAL_FRACTION 4
QT_BEGIN_NAMESPACE
-class QDeclarativeImageReaderEvent : public QEvent
+class QDeclarativePixmapReader;
+class QDeclarativePixmapData;
+class QDeclarativePixmapReply : public QObject
{
+ Q_OBJECT
public:
enum ReadError { NoError, Loading, Decoding };
- QDeclarativeImageReaderEvent(QDeclarativeImageReaderEvent::ReadError err, const QString &errStr, const QImage &img)
- : QEvent(QEvent::User), error(err), errorString(errStr), image(img) {}
+ QDeclarativePixmapReply(QDeclarativePixmapData *);
+ ~QDeclarativePixmapReply();
- ReadError error;
- QString errorString;
- QImage image;
+ QDeclarativePixmapData *data;
+ QDeclarativePixmapReader *reader;
+
+ bool loading;
+ int redirectCount;
+
+ class Event : public QEvent {
+ public:
+ Event(ReadError, const QString &, const QSize &, const QImage &);
+
+ ReadError error;
+ QString errorString;
+ QSize implicitSize;
+ QImage image;
+ };
+ void postReply(ReadError, const QString &, const QSize &, const QImage &);
+
+
+Q_SIGNALS:
+ void finished();
+ void downloadProgress(qint64, qint64);
+
+protected:
+ bool event(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QDeclarativePixmapReply)
+
+public:
+ static int finishedIndex;
+ static int downloadProgressIndex;
};
-class QDeclarativeImageRequestHandler;
-class QDeclarativeImageReader : public QThread
+class QDeclarativePixmapData;
+class QDeclarativePixmapReader : public QThread
{
Q_OBJECT
public:
- QDeclarativeImageReader(QDeclarativeEngine *eng);
- ~QDeclarativeImageReader();
+ QDeclarativePixmapReader(QDeclarativeEngine *eng);
+ ~QDeclarativePixmapReader();
- QDeclarativePixmapReply *getImage(const QUrl &url, int req_width, int req_height);
+ QDeclarativePixmapReply *getImage(QDeclarativePixmapData *);
void cancel(QDeclarativePixmapReply *rep);
- static QDeclarativeImageReader *instance(QDeclarativeEngine *engine);
+ static QDeclarativePixmapReader *instance(QDeclarativeEngine *engine);
protected:
void run();
+private slots:
+ void networkRequestDone();
+
private:
+ void processJobs();
+ void processJob(QDeclarativePixmapReply *);
+
QList<QDeclarativePixmapReply*> jobs;
QList<QDeclarativePixmapReply*> cancelled;
QDeclarativeEngine *engine;
- QDeclarativeImageRequestHandler *handler;
QObject *eventLoopQuitHack;
+
QMutex mutex;
+ class ThreadObject : public QObject {
+ public:
+ ThreadObject(QDeclarativePixmapReader *);
+ void processJobs();
+ virtual bool event(QEvent *e);
+ private:
+ QDeclarativePixmapReader *reader;
+ } *threadObject;
+ QWaitCondition waitCondition;
+
+ QNetworkAccessManager *networkAccessManager();
+ QNetworkAccessManager *accessManager;
+
+ QHash<QNetworkReply*,QDeclarativePixmapReply*> replies;
- static QHash<QDeclarativeEngine *,QDeclarativeImageReader*> readers;
+ static int replyDownloadProgress;
+ static int replyFinished;
+ static int downloadProgress;
+ static int thisNetworkRequestDone;
+ static QHash<QDeclarativeEngine *,QDeclarativePixmapReader*> readers;
static QMutex readerMutex;
- friend class QDeclarativeImageRequestHandler;
};
-QHash<QDeclarativeEngine *,QDeclarativeImageReader*> QDeclarativeImageReader::readers;
-QMutex QDeclarativeImageReader::readerMutex;
-
-
-class QDeclarativeImageRequestHandler : public QObject
+class QDeclarativePixmapData
{
- Q_OBJECT
public:
- QDeclarativeImageRequestHandler(QDeclarativeImageReader *read, QDeclarativeEngine *eng)
- : QObject(), accessManager(0), engine(eng), reader(read), redirectCount(0)
+ QDeclarativePixmapData(const QUrl &u, const QSize &s, const QString &e)
+ : refCount(1), inCache(false), pixmapStatus(QDeclarativePixmap::Error),
+ url(u), errorString(e), requestSize(s), reply(0), prevUnreferenced(0),
+ prevUnreferencedPtr(0), nextUnreferenced(0)
{
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
- QDeclarativePixmapReply *getImage(const QUrl &url, int req_width, int req_height);
- void cancel(QDeclarativePixmapReply *reply);
-
-protected:
- bool event(QEvent *event);
+ QDeclarativePixmapData(const QUrl &u, const QSize &r)
+ : refCount(1), inCache(false), pixmapStatus(QDeclarativePixmap::Loading),
+ url(u), requestSize(r), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0),
+ nextUnreferenced(0)
+ {
+ }
-private slots:
- void networkRequestDone();
+ QDeclarativePixmapData(const QUrl &u, const QPixmap &p, const QSize &s, const QSize &r)
+ : refCount(1), inCache(false), privatePixmap(false), pixmapStatus(QDeclarativePixmap::Ready),
+ url(u), pixmap(p), implicitSize(s), requestSize(r), reply(0), prevUnreferenced(0),
+ prevUnreferencedPtr(0), nextUnreferenced(0)
+ {
+ }
-private:
- QNetworkAccessManager *networkAccessManager() {
- if (!accessManager)
- accessManager = QDeclarativeEnginePrivate::get(engine)->createNetworkAccessManager(this);
- return accessManager;
+ QDeclarativePixmapData(const QPixmap &p)
+ : refCount(1), inCache(false), privatePixmap(true), pixmapStatus(QDeclarativePixmap::Ready),
+ pixmap(p), implicitSize(p.size()), requestSize(p.size()), reply(0), prevUnreferenced(0),
+ prevUnreferencedPtr(0), nextUnreferenced(0)
+ {
}
- QHash<QNetworkReply*,QDeclarativePixmapReply*> replies;
- QNetworkAccessManager *accessManager;
- QDeclarativeEngine *engine;
- QDeclarativeImageReader *reader;
- int redirectCount;
+ int cost() const;
+ void addref();
+ void release();
+ void addToCache();
+ void removeFromCache();
- static int replyDownloadProgress;
- static int replyFinished;
- static int downloadProgress;
- static int thisNetworkRequestDone;
+ uint refCount;
+
+ bool inCache:1;
+ bool privatePixmap:1;
+
+ QDeclarativePixmap::Status pixmapStatus;
+ QUrl url;
+ QString errorString;
+ QPixmap pixmap;
+ QSize implicitSize;
+ QSize requestSize;
+
+ QDeclarativePixmapReply *reply;
+
+ QDeclarativePixmapData *prevUnreferenced;
+ QDeclarativePixmapData**prevUnreferencedPtr;
+ QDeclarativePixmapData *nextUnreferenced;
};
-//===========================================================================
+int QDeclarativePixmapReply::finishedIndex = -1;
+int QDeclarativePixmapReply::downloadProgressIndex = -1;
+
+// XXX
+QHash<QDeclarativeEngine *,QDeclarativePixmapReader*> QDeclarativePixmapReader::readers;
+QMutex QDeclarativePixmapReader::readerMutex;
+
+int QDeclarativePixmapReader::replyDownloadProgress = -1;
+int QDeclarativePixmapReader::replyFinished = -1;
+int QDeclarativePixmapReader::downloadProgress = -1;
+int QDeclarativePixmapReader::thisNetworkRequestDone = -1;
-static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int req_width, int req_height)
+
+void QDeclarativePixmapReply::postReply(ReadError error, const QString &errorString,
+ const QSize &implicitSize, const QImage &image)
+{
+ loading = false;
+ QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, image));
+}
+
+QDeclarativePixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, const QImage &i)
+: QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), image(i)
+{
+}
+
+QNetworkAccessManager *QDeclarativePixmapReader::networkAccessManager()
+{
+ if (!accessManager) {
+ Q_ASSERT(threadObject);
+ accessManager = QDeclarativeEnginePrivate::get(engine)->createNetworkAccessManager(threadObject);
+ }
+ return accessManager;
+}
+
+static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize,
+ const QSize &requestSize)
{
QImageReader imgio(dev);
@@ -163,17 +268,17 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
}
bool scaled = false;
- if (req_width > 0 || req_height > 0) {
+ if (requestSize.width() > 0 || requestSize.height() > 0) {
QSize s = imgio.size();
- if (req_width && (force_scale || req_width < s.width())) {
- if (req_height <= 0)
- s.setHeight(s.height()*req_width/s.width());
- s.setWidth(req_width); scaled = true;
+ if (requestSize.width() && (force_scale || requestSize.width() < s.width())) {
+ if (requestSize.height() <= 0)
+ s.setHeight(s.height()*requestSize.width()/s.width());
+ s.setWidth(requestSize.width()); scaled = true;
}
- if (req_height && (force_scale || req_height < s.height())) {
- if (req_width <= 0)
- s.setWidth(s.width()*req_height/s.height());
- s.setHeight(req_height); scaled = true;
+ if (requestSize.height() && (force_scale || requestSize.height() < s.height())) {
+ if (requestSize.width() <= 0)
+ s.setWidth(s.width()*requestSize.height()/s.height());
+ s.setHeight(requestSize.height()); scaled = true;
}
if (scaled) { imgio.setScaledSize(s); }
}
@@ -187,130 +292,39 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
return true;
} else {
if (errorString)
- *errorString = QDeclarativePixmapCache::tr("Error decoding: %1: %2").arg(url.toString())
+ *errorString = QDeclarativePixmap::tr("Error decoding: %1: %2").arg(url.toString())
.arg(imgio.errorString());
return false;
}
}
-
-//===========================================================================
-
-int QDeclarativeImageRequestHandler::replyDownloadProgress = -1;
-int QDeclarativeImageRequestHandler::replyFinished = -1;
-int QDeclarativeImageRequestHandler::downloadProgress = -1;
-int QDeclarativeImageRequestHandler::thisNetworkRequestDone = -1;
-
-typedef QHash<QUrl, QSize> QDeclarativePixmapSizeHash;
-Q_GLOBAL_STATIC(QDeclarativePixmapSizeHash, qmlOriginalSizes);
-
-bool QDeclarativeImageRequestHandler::event(QEvent *event)
+QDeclarativePixmapReader::QDeclarativePixmapReader(QDeclarativeEngine *eng)
+: QThread(eng), engine(eng), threadObject(0), accessManager(0)
{
- if (event->type() == QEvent::User) {
- if (replyDownloadProgress == -1) {
- replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
- replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()");
- downloadProgress = QDeclarativePixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
- thisNetworkRequestDone = QDeclarativeImageRequestHandler::staticMetaObject.indexOfSlot("networkRequestDone()");
- }
-
- while (1) {
- reader->mutex.lock();
-
- if (reader->cancelled.count()) {
- for (int i = 0; i < reader->cancelled.count(); ++i) {
- QDeclarativePixmapReply *job = reader->cancelled.at(i);
- QNetworkReply *reply = replies.key(job, 0);
- if (reply && reply->isRunning()) {
- // cancel any jobs already started
- replies.remove(reply);
- reply->close();
- job->release(true);
- } else {
- // remove from pending job list
- for (int j = 0; j < reader->jobs.count(); ++j) {
- if (reader->jobs.at(j) == job) {
- reader->jobs.removeAt(j);
- job->release(true);
- break;
- }
- }
- }
- }
- reader->cancelled.clear();
- }
-
- if (!reader->jobs.count() || replies.count() > maxImageRequestCount) {
- reader->mutex.unlock();
- break;
- }
+ eventLoopQuitHack = new QObject;
+ eventLoopQuitHack->moveToThread(this);
+ connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
+ start(QThread::IdlePriority);
+}
- QDeclarativePixmapReply *runningJob = reader->jobs.takeLast();
- QUrl url = runningJob->url();
- reader->mutex.unlock();
-
- // fetch
- if (url.scheme() == QLatin1String("image")) {
- // Use QmlImageProvider
- QSize read_impsize;
- QImage image = QDeclarativeEnginePrivate::get(engine)->getImageFromProvider(url, &read_impsize, QSize(runningJob->forcedWidth(),runningJob->forcedHeight()));
- qmlOriginalSizes()->insert(url, read_impsize);
- QDeclarativeImageReaderEvent::ReadError errorCode = QDeclarativeImageReaderEvent::NoError;
- QString errorStr;
- if (image.isNull()) {
- errorCode = QDeclarativeImageReaderEvent::Loading;
- errorStr = QDeclarativePixmapCache::tr("Failed to get image from provider: %1").arg(url.toString());
- }
- QCoreApplication::postEvent(runningJob, new QDeclarativeImageReaderEvent(errorCode, errorStr, image));
- } else {
- QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
- // Image is local - load/decode immediately
- QImage image;
- QDeclarativeImageReaderEvent::ReadError errorCode = QDeclarativeImageReaderEvent::NoError;
- QString errorStr;
- QFile f(lf);
- if (f.open(QIODevice::ReadOnly)) {
- QSize read_impsize;
- if (readImage(url, &f, &image, &errorStr, &read_impsize, runningJob->forcedWidth(),runningJob->forcedHeight())) {
- qmlOriginalSizes()->insert(url, read_impsize);
- } else {
- errorCode = QDeclarativeImageReaderEvent::Loading;
- }
- } else {
- errorStr = QDeclarativePixmapCache::tr("Cannot open: %1").arg(url.toString());
- errorCode = QDeclarativeImageReaderEvent::Loading;
- }
- QCoreApplication::postEvent(runningJob, new QDeclarativeImageReaderEvent(errorCode, errorStr, image));
- } else {
- // Network resource
- 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;
- }
+QDeclarativePixmapReader::~QDeclarativePixmapReader()
+{
+ readerMutex.lock();
+ readers.remove(engine);
+ readerMutex.unlock();
- return QObject::event(event);
+ eventLoopQuitHack->deleteLater();
+ wait();
}
-#define IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION 16
-
-void QDeclarativeImageRequestHandler::networkRequestDone()
+void QDeclarativePixmapReader::networkRequestDone()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
QDeclarativePixmapReply *job = replies.take(reply);
if (job) {
- redirectCount++;
- if (redirectCount < IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION) {
+ job->redirectCount++;
+ if (job->redirectCount < IMAGEREQUEST_MAX_REDIRECT_RECURSION) {
QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = reply->url().resolved(redirect.toUrl());
@@ -327,62 +341,147 @@ void QDeclarativeImageRequestHandler::networkRequestDone()
return;
}
}
- redirectCount=0;
QImage image;
- QDeclarativeImageReaderEvent::ReadError error;
+ QDeclarativePixmapReply::ReadError error = QDeclarativePixmapReply::NoError;
QString errorString;
+ QSize readSize;
if (reply->error()) {
- error = QDeclarativeImageReaderEvent::Loading;
+ error = QDeclarativePixmapReply::Loading;
errorString = reply->errorString();
} else {
- QSize read_impsize;
QByteArray all = reply->readAll();
QBuffer buff(&all);
buff.open(QIODevice::ReadOnly);
- if (readImage(reply->url(), &buff, &image, &errorString, &read_impsize, job->forcedWidth(), job->forcedHeight())) {
- qmlOriginalSizes()->insert(reply->url(), read_impsize);
- error = QDeclarativeImageReaderEvent::NoError;
- } else {
- error = QDeclarativeImageReaderEvent::Decoding;
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->data->requestSize)) {
+ error = QDeclarativePixmapReply::Decoding;
}
}
// send completion event to the QDeclarativePixmapReply
- QCoreApplication::postEvent(job, new QDeclarativeImageReaderEvent(error, errorString, image));
+ mutex.lock();
+ if (!cancelled.contains(job)) job->postReply(error, errorString, readSize, image);
+ mutex.unlock();
}
- // 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();
+
+ // kick off event loop again incase we have dropped below max request count
+ threadObject->processJobs();
}
-//===========================================================================
+QDeclarativePixmapReader::ThreadObject::ThreadObject(QDeclarativePixmapReader *i)
+: reader(i)
+{
+}
-QDeclarativeImageReader::QDeclarativeImageReader(QDeclarativeEngine *eng)
- : QThread(eng), engine(eng), handler(0)
+void QDeclarativePixmapReader::ThreadObject::processJobs()
+{
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+}
+
+bool QDeclarativePixmapReader::ThreadObject::event(QEvent *e)
{
- eventLoopQuitHack = new QObject;
- eventLoopQuitHack->moveToThread(this);
- connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
- start(QThread::IdlePriority);
+ if (e->type() == QEvent::User) {
+ reader->processJobs();
+ return true;
+ } else {
+ return QObject::event(e);
+ }
}
-QDeclarativeImageReader::~QDeclarativeImageReader()
+void QDeclarativePixmapReader::processJobs()
{
- readerMutex.lock();
- readers.remove(engine);
- readerMutex.unlock();
+ QMutexLocker locker(&mutex);
+
+ while (true) {
+ if (cancelled.isEmpty() && (jobs.isEmpty() || replies.count() >= IMAGEREQUEST_MAX_REQUEST_COUNT))
+ return; // Nothing else to do
+
+ // Clean cancelled jobs
+ if (cancelled.count()) {
+ for (int i = 0; i < cancelled.count(); ++i) {
+ QDeclarativePixmapReply *job = cancelled.at(i);
+ QNetworkReply *reply = replies.key(job, 0);
+ if (reply && reply->isRunning()) {
+ // cancel any jobs already started
+ replies.remove(reply);
+ reply->close();
+ }
+ delete job;
+ }
+ cancelled.clear();
+ }
- eventLoopQuitHack->deleteLater();
- wait();
+ if (!jobs.isEmpty() && replies.count() < IMAGEREQUEST_MAX_REQUEST_COUNT) {
+ QDeclarativePixmapReply *runningJob = jobs.takeLast();
+ runningJob->loading = true;
+
+ locker.unlock();
+ processJob(runningJob);
+ locker.relock();
+ }
+ }
}
-QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *engine)
+void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob)
+{
+ QUrl url = runningJob->data->url;
+
+ // fetch
+ if (url.scheme() == QLatin1String("image")) {
+ // Use QmlImageProvider
+ QSize readSize;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QImage image = ep->getImageFromProvider(url, &readSize, runningJob->data->requestSize);
+
+ QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
+ QString errorStr;
+ if (image.isNull()) {
+ errorCode = QDeclarativePixmapReply::Loading;
+ errorStr = QDeclarativePixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+
+ mutex.lock();
+ if (!cancelled.contains(runningJob)) runningJob->postReply(errorCode, errorStr, readSize, image);
+ mutex.unlock();
+ } else {
+ QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
+ if (!lf.isEmpty()) {
+ // Image is local - load/decode immediately
+ QImage image;
+ QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
+ QString errorStr;
+ QFile f(lf);
+ QSize readSize;
+ if (f.open(QIODevice::ReadOnly)) {
+ if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->data->requestSize))
+ errorCode = QDeclarativePixmapReply::Loading;
+ } else {
+ errorStr = QDeclarativePixmap::tr("Cannot open: %1").arg(url.toString());
+ errorCode = QDeclarativePixmapReply::Loading;
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob)) runningJob->postReply(errorCode, errorStr, readSize, image);
+ mutex.unlock();
+ } else {
+ // Network resource
+ 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);
+ }
+ }
+}
+
+QDeclarativePixmapReader *QDeclarativePixmapReader::instance(QDeclarativeEngine *engine)
{
readerMutex.lock();
- QDeclarativeImageReader *reader = readers.value(engine);
+ QDeclarativePixmapReader *reader = readers.value(engine);
if (!reader) {
- reader = new QDeclarativeImageReader(engine);
+ reader = new QDeclarativePixmapReader(engine);
readers.insert(engine, reader);
}
readerMutex.unlock();
@@ -390,348 +489,558 @@ QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *e
return reader;
}
-QDeclarativePixmapReply *QDeclarativeImageReader::getImage(const QUrl &url, int req_width, int req_height)
+QDeclarativePixmapReply *QDeclarativePixmapReader::getImage(QDeclarativePixmapData *data)
{
mutex.lock();
- QDeclarativePixmapReply *reply = new QDeclarativePixmapReply(this, url, req_width, req_height);
- reply->addRef();
- reply->setLoading();
+ QDeclarativePixmapReply *reply = new QDeclarativePixmapReply(data);
+ reply->reader = this;
jobs.append(reply);
- if (jobs.count() == 1 && handler)
- QCoreApplication::postEvent(handler, new QEvent(QEvent::User));
+ // XXX
+ if (threadObject) threadObject->processJobs();
mutex.unlock();
return reply;
}
-void QDeclarativeImageReader::cancel(QDeclarativePixmapReply *reply)
+void QDeclarativePixmapReader::cancel(QDeclarativePixmapReply *reply)
{
mutex.lock();
- if (reply->isLoading()) {
- // Add to cancel list to be cancelled in reader thread.
+ if (reply->loading) {
cancelled.append(reply);
- if (cancelled.count() == 1 && handler)
- QCoreApplication::postEvent(handler, new QEvent(QEvent::User));
+ // XXX
+ if (threadObject) threadObject->processJobs();
+ } else {
+ jobs.removeAll(reply);
+ delete reply;
}
mutex.unlock();
}
-void QDeclarativeImageReader::run()
+void QDeclarativePixmapReader::run()
{
- readerMutex.lock();
- handler = new QDeclarativeImageRequestHandler(this, engine);
- readerMutex.unlock();
+ if (replyDownloadProgress == -1) {
+ const QMetaObject *nr = &QNetworkReply::staticMetaObject;
+ const QMetaObject *pr = &QDeclarativePixmapReply::staticMetaObject;
+ const QMetaObject *ir = &QDeclarativePixmapReader::staticMetaObject;
+ replyDownloadProgress = nr->indexOfSignal("downloadProgress(qint64,qint64)");
+ replyFinished = nr->indexOfSignal("finished()");
+ downloadProgress = pr->indexOfSignal("downloadProgress(qint64,qint64)");
+ thisNetworkRequestDone = ir->indexOfSlot("networkRequestDone()");
+ }
+
+ mutex.lock();
+ threadObject = new ThreadObject(this);
+ mutex.unlock();
+ processJobs();
exec();
- delete handler;
- handler = 0;
+ delete threadObject;
+ threadObject = 0;
}
-//===========================================================================
-
-/*!
- \internal
- \class QDeclarativePixmapCache
- \brief Enacapsultes a pixmap for QDeclarativeGraphics items.
+class QDeclarativePixmapKey
+{
+public:
+ const QUrl *url;
+ const QSize *size;
+};
- This class is NOT reentrant.
- */
+inline bool operator==(const QDeclarativePixmapKey &lhs, const QDeclarativePixmapKey &rhs)
+{
+ return *lhs.size == *rhs.size && *lhs.url == *rhs.url;
+}
-typedef QHash<QUrl, QDeclarativePixmapReply *> QDeclarativePixmapReplyHash;
-Q_GLOBAL_STATIC(QDeclarativePixmapReplyHash, qmlActivePixmapReplies);
+inline uint qHash(const QDeclarativePixmapKey &key)
+{
+ return qHash(*key.url) ^ key.size->width() ^ key.size->height();
+}
-class QDeclarativePixmapReplyPrivate : public QObjectPrivate
+class QDeclarativePixmapStore : public QObject
{
- Q_DECLARE_PUBLIC(QDeclarativePixmapReply)
+ Q_OBJECT
+public:
+ QDeclarativePixmapStore();
+
+ void unreferencePixmap(QDeclarativePixmapData *);
+ void referencePixmap(QDeclarativePixmapData *);
+
+protected:
+ virtual void timerEvent(QTimerEvent *);
public:
- QDeclarativePixmapReplyPrivate(QDeclarativeImageReader *r, const QUrl &u, int req_width, int req_height)
- : QObjectPrivate(), refCount(1), url(u), status(QDeclarativePixmapReply::Loading), loading(false), reader(r),
- forced_width(req_width), forced_height(req_height)
- {
- }
+ QHash<QDeclarativePixmapKey, QDeclarativePixmapData *> m_cache;
- int refCount;
- QUrl url;
- QPixmap pixmap; // ensure reference to pixmap so QPixmapCache does not discard
- QDeclarativePixmapReply::Status status;
- bool loading;
- QDeclarativeImageReader *reader;
- int forced_width, forced_height;
- QString errorString;
-};
+private:
+ QDeclarativePixmapData *m_unreferencedPixmaps;
+ QDeclarativePixmapData *m_lastUnreferencedPixmap;
+ int m_unreferencedCost;
+ int m_timerId;
+};
+Q_GLOBAL_STATIC(QDeclarativePixmapStore, pixmapStore);
-QDeclarativePixmapReply::QDeclarativePixmapReply(QDeclarativeImageReader *reader, const QUrl &url, int req_width, int req_height)
- : QObject(*new QDeclarativePixmapReplyPrivate(reader, url, req_width, req_height), 0)
+QDeclarativePixmapStore::QDeclarativePixmapStore()
+: m_unreferencedPixmaps(0), m_lastUnreferencedPixmap(0), m_unreferencedCost(0), m_timerId(-1)
{
}
-QDeclarativePixmapReply::~QDeclarativePixmapReply()
+void QDeclarativePixmapStore::unreferencePixmap(QDeclarativePixmapData *data)
{
+ Q_ASSERT(data->prevUnreferenced == 0);
+ Q_ASSERT(data->prevUnreferencedPtr == 0);
+ Q_ASSERT(data->nextUnreferenced == 0);
+
+ data->nextUnreferenced = m_unreferencedPixmaps;
+ data->prevUnreferencedPtr = &m_unreferencedPixmaps;
+
+ m_unreferencedPixmaps = data;
+ if (m_unreferencedPixmaps->nextUnreferenced) {
+ m_unreferencedPixmaps->nextUnreferenced->prevUnreferenced = m_unreferencedPixmaps;
+ m_unreferencedPixmaps->nextUnreferenced->prevUnreferencedPtr = &m_unreferencedPixmaps->nextUnreferenced;
+ }
+
+ if (!m_lastUnreferencedPixmap)
+ m_lastUnreferencedPixmap = data;
+
+ m_unreferencedCost += data->cost();
+
+ if (m_timerId == -1)
+ startTimer(CACHE_EXPIRE_TIME * 1000);
}
-const QUrl &QDeclarativePixmapReply::url() const
+void QDeclarativePixmapStore::referencePixmap(QDeclarativePixmapData *data)
{
- Q_D(const QDeclarativePixmapReply);
- return d->url;
+ Q_ASSERT(data->prevUnreferencedPtr);
+
+ *data->prevUnreferencedPtr = data->nextUnreferenced;
+ if (data->nextUnreferenced) {
+ data->nextUnreferenced->prevUnreferencedPtr = data->prevUnreferencedPtr;
+ data->nextUnreferenced->prevUnreferenced = data->prevUnreferenced;
+ }
+ if (m_lastUnreferencedPixmap == data)
+ m_lastUnreferencedPixmap = data->prevUnreferenced;
+
+ data->nextUnreferenced = 0;
+ data->prevUnreferencedPtr = 0;
+ data->prevUnreferenced = 0;
+
+ m_unreferencedCost -= data->cost();
}
-int QDeclarativePixmapReply::forcedWidth() const
+void QDeclarativePixmapStore::timerEvent(QTimerEvent *)
{
- Q_D(const QDeclarativePixmapReply);
- return d->forced_width;
+ int removalCost = m_unreferencedCost / CACHE_REMOVAL_FRACTION;
+
+ while (removalCost > 0 && m_lastUnreferencedPixmap) {
+ QDeclarativePixmapData *data = m_lastUnreferencedPixmap;
+ Q_ASSERT(data->nextUnreferenced == 0);
+
+ *data->prevUnreferencedPtr = 0;
+ m_lastUnreferencedPixmap = data->prevUnreferenced;
+ data->prevUnreferencedPtr = 0;
+ data->prevUnreferenced = 0;
+
+ removalCost -= data->cost();
+ data->removeFromCache();
+ delete data;
+ }
+
+ if (m_unreferencedPixmaps == 0) {
+ killTimer(m_timerId);
+ m_timerId = -1;
+ }
}
-int QDeclarativePixmapReply::forcedHeight() const
+QDeclarativePixmapReply::QDeclarativePixmapReply(QDeclarativePixmapData *d)
+: data(d), reader(0), loading(false), redirectCount(0)
{
- Q_D(const QDeclarativePixmapReply);
- return d->forced_height;
+ if (finishedIndex == -1) {
+ finishedIndex = QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()");
+ downloadProgressIndex = QDeclarativePixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
+ }
}
-QSize QDeclarativePixmapReply::implicitSize() const
+QDeclarativePixmapReply::~QDeclarativePixmapReply()
{
- Q_D(const QDeclarativePixmapReply);
- QDeclarativePixmapSizeHash::Iterator iter = qmlOriginalSizes()->find(d->url);
- if (iter != qmlOriginalSizes()->end())
- return *iter;
- else
- return QSize();
}
bool QDeclarativePixmapReply::event(QEvent *event)
{
- Q_D(QDeclarativePixmapReply);
if (event->type() == QEvent::User) {
- d->loading = false;
- if (!release(true)) {
- QDeclarativeImageReaderEvent *de = static_cast<QDeclarativeImageReaderEvent*>(event);
- d->status = (de->error == QDeclarativeImageReaderEvent::NoError) ? Ready : Error;
- if (d->status == Ready)
- d->pixmap = QPixmap::fromImage(de->image);
- else
- d->errorString = de->errorString;
- QByteArray key = d->url.toEncoded(QUrl::FormattingOption(0x100));
- if (d->forced_width > 0 || d->forced_height > 0) {
- key += ':';
- key += QByteArray::number(d->forced_width);
- key += 'x';
- key += QByteArray::number(d->forced_height);
+
+ if (data) {
+ Event *de = static_cast<Event *>(event);
+ data->pixmapStatus = (de->error == NoError) ? QDeclarativePixmap::Ready : QDeclarativePixmap::Error;
+
+ if (data->pixmapStatus == QDeclarativePixmap::Ready) {
+ data->pixmap = QPixmap::fromImage(de->image);
+ data->implicitSize = de->implicitSize;
+ } else {
+ data->errorString = de->errorString;
+ data->removeFromCache(); // We don't continue to cache error'd pixmaps
}
- QString strKey = QString::fromLatin1(key.constData(), key.count());
- QPixmapCache::insert(strKey, d->pixmap); // note: may fail (returns false)
+
+ data->reply = 0;
emit finished();
}
+
+ delete this;
return true;
+ } else {
+ return QObject::event(event);
}
-
- return QObject::event(event);
}
-QString QDeclarativePixmapReply::errorString() const
+int QDeclarativePixmapData::cost() const
{
- Q_D(const QDeclarativePixmapReply);
- return d->errorString;
+ return pixmap.width() * pixmap.height() * pixmap.depth();
}
-QDeclarativePixmapReply::Status QDeclarativePixmapReply::status() const
+void QDeclarativePixmapData::addref()
{
- Q_D(const QDeclarativePixmapReply);
- return d->status;
+ ++refCount;
+ if (prevUnreferencedPtr)
+ pixmapStore()->referencePixmap(this);
}
-bool QDeclarativePixmapReply::isLoading() const
+void QDeclarativePixmapData::release()
{
- Q_D(const QDeclarativePixmapReply);
- return d->loading;
+ Q_ASSERT(refCount > 0);
+ --refCount;
+
+ if (refCount == 0) {
+ if (reply) {
+ reply->data = 0;
+ reply->reader->cancel(reply);
+ reply = 0;
+ }
+
+ if (pixmapStatus == QDeclarativePixmap::Ready) {
+ pixmapStore()->unreferencePixmap(this);
+ } else {
+ removeFromCache();
+ delete this;
+ }
+ }
}
-void QDeclarativePixmapReply::setLoading()
+void QDeclarativePixmapData::addToCache()
{
- Q_D(QDeclarativePixmapReply);
- d->loading = true;
+ if (!inCache) {
+ QDeclarativePixmapKey key = { &url, &requestSize };
+ pixmapStore()->m_cache.insert(key, this);
+ inCache = true;
+ }
}
-void QDeclarativePixmapReply::addRef()
+void QDeclarativePixmapData::removeFromCache()
{
- Q_D(QDeclarativePixmapReply);
- ++d->refCount;
+ if (inCache) {
+ QDeclarativePixmapKey key = { &url, &requestSize };
+ pixmapStore()->m_cache.remove(key);
+ inCache = false;
+ }
}
-bool QDeclarativePixmapReply::release(bool defer)
+static QDeclarativePixmapData* createPixmapDataSync(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, bool *ok)
{
- Q_D(QDeclarativePixmapReply);
- Q_ASSERT(d->refCount > 0);
- --d->refCount;
- if (d->refCount == 0) {
- qmlActivePixmapReplies()->remove(d->url);
- 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);
- d->reader->cancel(this);
+ if (url.scheme() == QLatin1String("image")) {
+ QSize readSize;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QDeclarativeImageProvider::ImageType imageType = ep->getImageProviderType(url);
+
+ switch (imageType) {
+ case QDeclarativeImageProvider::Image:
+ {
+ QImage image = ep->getImageFromProvider(url, &readSize, requestSize);
+ if (!image.isNull()) {
+ *ok = true;
+ return new QDeclarativePixmapData(url, QPixmap::fromImage(image), readSize, requestSize);
+ }
+ }
+ case QDeclarativeImageProvider::Pixmap:
+ {
+ QPixmap pixmap = ep->getPixmapFromProvider(url, &readSize, requestSize);
+ if (!pixmap.isNull()) {
+ *ok = true;
+ return new QDeclarativePixmapData(url, pixmap, readSize, requestSize);
+ }
+ }
+ }
+
+ // no matching provider, or provider has bad image type, or provider returned null image
+ return new QDeclarativePixmapData(url, requestSize,
+ QDeclarativePixmap::tr("Failed to get image from provider: %1").arg(url.toString()));
}
- return false;
+ QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
+ if (localFile.isEmpty())
+ return 0;
+
+ QFile f(localFile);
+ QSize readSize;
+ QString errorString;
+
+ if (f.open(QIODevice::ReadOnly)) {
+ QImage image;
+ if (readImage(url, &f, &image, &errorString, &readSize, requestSize)) {
+ *ok = true;
+ return new QDeclarativePixmapData(url, QPixmap::fromImage(image), readSize, requestSize);
+ }
+ } else {
+ errorString = QDeclarativePixmap::tr("Cannot open: %1").arg(url.toString());
+ }
+ return new QDeclarativePixmapData(url, requestSize, errorString);
}
-/*!
- Finds the cached pixmap corresponding to \a url.
- If the image is a network resource and has not yet
- been retrieved and cached, request() must be called.
- Returns Ready, or Error if the image has been retrieved,
- otherwise the current retrieval status.
+struct QDeclarativePixmapNull {
+ QUrl url;
+ QPixmap pixmap;
+ QSize size;
+};
+Q_GLOBAL_STATIC(QDeclarativePixmapNull, nullPixmap);
- If \a async is false the image will be loaded and decoded immediately;
- otherwise the image will be loaded and decoded in a separate thread.
+QDeclarativePixmap::QDeclarativePixmap()
+: d(0)
+{
+}
- If \a req_width and \a req_height are non-zero, they are used for
- the size of the rendered pixmap rather than the intrinsic size of the image.
- Different request sizes add different cache items.
+QDeclarativePixmap::QDeclarativePixmap(QDeclarativeEngine *engine, const QUrl &url)
+: d(0)
+{
+ load(engine, url);
+}
- Note that images sourced from the network will always be loaded and
- decoded asynchonously.
-*/
-QDeclarativePixmapReply::Status QDeclarativePixmapCache::get(const QUrl& url, QPixmap *pixmap, QString *errorString, QSize *impsize, bool async, int req_width, int req_height)
+QDeclarativePixmap::QDeclarativePixmap(QDeclarativeEngine *engine, const QUrl &url, const QSize &size)
+: d(0)
{
- QDeclarativePixmapReply::Status status = QDeclarativePixmapReply::Unrequested;
- QByteArray key = url.toEncoded(QUrl::FormattingOption(0x100));
+ load(engine, url, size);
+}
- if (req_width > 0 || req_height > 0) {
- key += ':';
- key += QByteArray::number(req_width);
- key += 'x';
- key += QByteArray::number(req_height);
+QDeclarativePixmap::~QDeclarativePixmap()
+{
+ if (d) {
+ d->release();
+ d = 0;
}
+}
- QString strKey = QString::fromLatin1(key.constData(), key.count());
+bool QDeclarativePixmap::isNull() const
+{
+ return d == 0;
+}
-#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
- if (!async) {
- QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
- status = QDeclarativePixmapReply::Ready;
- if (!QPixmapCache::find(strKey,pixmap)) {
- QFile f(lf);
- QSize read_impsize;
- if (f.open(QIODevice::ReadOnly)) {
- QImage image;
- if (readImage(url, &f, &image, errorString, &read_impsize, req_width, req_height)) {
- *pixmap = QPixmap::fromImage(image);
- } else {
- *pixmap = QPixmap();
- status = QDeclarativePixmapReply::Error;
- }
- } else {
- if (errorString)
- *errorString = tr("Cannot open: %1").arg(url.toString());
- *pixmap = QPixmap();
- status = QDeclarativePixmapReply::Error;
- }
- if (status == QDeclarativePixmapReply::Ready) {
- QPixmapCache::insert(strKey, *pixmap);
- qmlOriginalSizes()->insert(url, read_impsize);
- }
- if (impsize)
- *impsize = read_impsize;
- } else {
- if (impsize) {
- QDeclarativePixmapSizeHash::Iterator iter = qmlOriginalSizes()->find(url);
- if (iter != qmlOriginalSizes()->end())
- *impsize = *iter;
- }
+bool QDeclarativePixmap::isReady() const
+{
+ return status() == Ready;
+}
+
+bool QDeclarativePixmap::isError() const
+{
+ return status() == Error;
+}
+
+bool QDeclarativePixmap::isLoading() const
+{
+ return status() == Loading;
+}
+
+QString QDeclarativePixmap::error() const
+{
+ if (d)
+ return d->errorString;
+ else
+ return QString();
+}
+
+QDeclarativePixmap::Status QDeclarativePixmap::status() const
+{
+ if (d)
+ return d->pixmapStatus;
+ else
+ return Null;
+}
+
+const QUrl &QDeclarativePixmap::url() const
+{
+ if (d)
+ return d->url;
+ else
+ return nullPixmap()->url;
+}
+
+const QSize &QDeclarativePixmap::implicitSize() const
+{
+ if (d)
+ return d->implicitSize;
+ else
+ return nullPixmap()->size;
+}
+
+const QSize &QDeclarativePixmap::requestSize() const
+{
+ if (d)
+ return d->requestSize;
+ else
+ return nullPixmap()->size;
+}
+
+const QPixmap &QDeclarativePixmap::pixmap() const
+{
+ if (d)
+ return d->pixmap;
+ else
+ return nullPixmap()->pixmap;
+}
+
+void QDeclarativePixmap::setPixmap(const QPixmap &p)
+{
+ clear();
+
+ if (!p.isNull())
+ d = new QDeclarativePixmapData(p);
+}
+
+int QDeclarativePixmap::width() const
+{
+ if (d)
+ return d->pixmap.width();
+ else
+ return 0;
+}
+
+int QDeclarativePixmap::height() const
+{
+ if (d)
+ return d->pixmap.height();
+ else
+ return 0;
+}
+
+QRect QDeclarativePixmap::rect() const
+{
+ if (d)
+ return d->pixmap.rect();
+ else
+ return QRect();
+}
+
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url)
+{
+ load(engine, url, QSize(), false);
+}
+
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, bool async)
+{
+ load(engine, url, QSize(), async);
+}
+
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &size)
+{
+ load(engine, url, size, false);
+}
+
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, bool async)
+{
+ if (d) { d->release(); d = 0; }
+
+ QDeclarativePixmapKey key = { &url, &requestSize };
+ QDeclarativePixmapStore *store = pixmapStore();
+
+ QHash<QDeclarativePixmapKey, QDeclarativePixmapData *>::Iterator iter = store->m_cache.find(key);
+
+ if (iter == store->m_cache.end()) {
+ if (async) {
+ // pixmaps can only be loaded synchronously
+ if (url.scheme() == QLatin1String("image")
+ && QDeclarativeEnginePrivate::get(engine)->getImageProviderType(url) == QDeclarativeImageProvider::Pixmap) {
+ async = false;
}
- return status;
- }
- }
-#endif
-
- QDeclarativePixmapReplyHash::Iterator iter = qmlActivePixmapReplies()->find(url);
- if (iter != qmlActivePixmapReplies()->end() && (*iter)->status() == QDeclarativePixmapReply::Ready) {
- // Must check this, since QPixmapCache::insert may have failed.
- *pixmap = (*iter)->d_func()->pixmap;
- status = (*iter)->status();
- (*iter)->release();
- } else if (QPixmapCache::find(strKey, pixmap)) {
- if (iter != qmlActivePixmapReplies()->end()) {
- status = (*iter)->status();
- if (errorString)
- *errorString = (*iter)->errorString();
- (*iter)->release();
- } else if (pixmap->isNull()) {
- status = QDeclarativePixmapReply::Error;
- if (errorString)
- *errorString = tr("Unknown Error loading %1").arg(url.toString());
- } else {
- status = QDeclarativePixmapReply::Ready;
}
- } else if (iter != qmlActivePixmapReplies()->end()) {
- status = QDeclarativePixmapReply::Loading;
- }
- if (impsize) {
- QDeclarativePixmapSizeHash::Iterator iter = qmlOriginalSizes()->find(url);
- if (iter != qmlOriginalSizes()->end())
- *impsize = *iter;
- }
- return status;
+ if (!async) {
+ bool ok = false;
+ d = createPixmapDataSync(engine, url, requestSize, &ok);
+ if (ok) {
+ d->addToCache();
+ return;
+ }
+ if (d) // loadable, but encountered error while loading
+ return;
+ }
+
+ if (!engine)
+ return;
+
+ QDeclarativePixmapReader *reader = QDeclarativePixmapReader::instance(engine);
+
+ d = new QDeclarativePixmapData(url, requestSize);
+ d->addToCache();
+
+ d->reply = reader->getImage(d);
+ } else {
+ d = *iter;
+ d->addref();
+ }
}
-/*!
- Starts a network request to load \a url.
+void QDeclarativePixmap::clear()
+{
+ if (d) {
+ d->release();
+ d = 0;
+ }
+}
- Returns a QDeclarativePixmapReply. Caller should connect to QDeclarativePixmapReply::finished()
- and call get() when the image is available.
+void QDeclarativePixmap::clear(QObject *obj)
+{
+ if (d) {
+ if (d->reply)
+ QObject::disconnect(d->reply, 0, obj, 0);
+ d->release();
+ d = 0;
+ }
+}
- The returned QDeclarativePixmapReply will be deleted when all request() calls are
- matched by a corresponding get() call.
-*/
-QDeclarativePixmapReply *QDeclarativePixmapCache::request(QDeclarativeEngine *engine, const QUrl &url, int req_width, int req_height)
+bool QDeclarativePixmap::connectFinished(QObject *object, const char *method)
{
- QDeclarativePixmapReplyHash::Iterator iter = qmlActivePixmapReplies()->find(url);
- if (iter == qmlActivePixmapReplies()->end()) {
- QDeclarativeImageReader *reader = QDeclarativeImageReader::instance(engine);
- QDeclarativePixmapReply *item = reader->getImage(url, req_width, req_height);
- iter = qmlActivePixmapReplies()->insert(url, item);
- } else {
- (*iter)->addRef();
+ if (!d || !d->reply) {
+ qWarning("QDeclarativePixmap: connectFinished() called when not loading.");
+ return false;
}
- return (*iter);
+ return QObject::connect(d->reply, SIGNAL(finished()), object, method);
}
-/*!
- Cancels a previous call to request().
+bool QDeclarativePixmap::connectFinished(QObject *object, int method)
+{
+ if (!d || !d->reply) {
+ qWarning("QDeclarativePixmap: connectFinished() called when not loading.");
+ return false;
+ }
- May also cancel loading (eg. if no other pending request).
+ return QMetaObject::connect(d->reply, QDeclarativePixmapReply::finishedIndex, object, method);
+}
- Any connections from the QDeclarativePixmapReply returned by request() to \a obj will be
- disconnected.
-*/
-void QDeclarativePixmapCache::cancel(const QUrl& url, QObject *obj)
+bool QDeclarativePixmap::connectDownloadProgress(QObject *object, const char *method)
{
- QDeclarativePixmapReplyHash::Iterator iter = qmlActivePixmapReplies()->find(url);
- if (iter == qmlActivePixmapReplies()->end())
- return;
+ if (!d || !d->reply) {
+ qWarning("QDeclarativePixmap: connectDownloadProgress() called when not loading.");
+ return false;
+ }
- QDeclarativePixmapReply *reply = *iter;
- if (obj)
- QObject::disconnect(reply, 0, obj, 0);
- reply->release();
+ return QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), object, method);
}
-/*!
- This function is mainly for test verification. It returns the number of
- requests that are still unfinished.
-*/
-int QDeclarativePixmapCache::pendingRequests()
+bool QDeclarativePixmap::connectDownloadProgress(QObject *object, int method)
{
- return qmlActivePixmapReplies()->count();
+ if (!d || !d->reply) {
+ qWarning("QDeclarativePixmap: connectDownloadProgress() called when not loading.");
+ return false;
+ }
+
+ return QMetaObject::connect(d->reply, QDeclarativePixmapReply::downloadProgressIndex, object, method);
}
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativepixmapcache_p.h b/src/declarative/util/qdeclarativepixmapcache_p.h
index 33d9de1..b4d88bd 100644
--- a/src/declarative/util/qdeclarativepixmapcache_p.h
+++ b/src/declarative/util/qdeclarativepixmapcache_p.h
@@ -42,69 +42,70 @@
#ifndef QDECLARATIVEPIXMAPCACHE_H
#define QDECLARATIVEPIXMAPCACHE_H
-#include <QtCore/QString>
-#include <QtGui/QPixmap>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qpixmap.h>
#include <QtCore/qurl.h>
-#include <QtCore/QCoreApplication>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QDeclarativeEngine;
-class QNetworkReply;
-class QDeclarativeImageReader;
-class QDeclarativePixmapReplyPrivate;
-class Q_DECLARATIVE_EXPORT QDeclarativePixmapReply : public QObject
+class QDeclarativeEngine;
+class QDeclarativePixmapData;
+class Q_DECLARATIVE_EXPORT QDeclarativePixmap
{
- Q_OBJECT
+ Q_DECLARE_TR_FUNCTIONS(QDeclarativePixmap)
public:
- ~QDeclarativePixmapReply();
+ QDeclarativePixmap();
+ QDeclarativePixmap(QDeclarativeEngine *, const QUrl &);
+ QDeclarativePixmap(QDeclarativeEngine *, const QUrl &, const QSize &);
+ ~QDeclarativePixmap();
- enum Status { Ready, Error, Unrequested, Loading };
- Status status() const;
- QString errorString() const;
+ enum Status { Null, Ready, Error, Loading };
+ bool isNull() const;
+ bool isReady() const;
+ bool isError() const;
+ bool isLoading() const;
+
+ Status status() const;
+ QString error() const;
const QUrl &url() const;
- int forcedWidth() const;
- int forcedHeight() const;
- QSize implicitSize() const;
+ const QSize &implicitSize() const;
+ const QSize &requestSize() const;
+ const QPixmap &pixmap() const;
+ void setPixmap(const QPixmap &);
-Q_SIGNALS:
- void finished();
- void downloadProgress(qint64, qint64);
+ QRect rect() const;
+ int width() const;
+ int height() const;
+ inline operator const QPixmap &() const;
-protected:
- bool event(QEvent *event);
+ void load(QDeclarativeEngine *, const QUrl &);
+ void load(QDeclarativeEngine *, const QUrl &, bool);
+ void load(QDeclarativeEngine *, const QUrl &, const QSize &);
+ void load(QDeclarativeEngine *, const QUrl &, const QSize &, bool);
-private:
- void addRef();
- bool release(bool defer=false);
- bool isLoading() const;
- void setLoading();
+ void clear();
+ void clear(QObject *);
+
+ bool connectFinished(QObject *, const char *);
+ bool connectFinished(QObject *, int);
+ bool connectDownloadProgress(QObject *, const char *);
+ bool connectDownloadProgress(QObject *, int);
private:
- QDeclarativePixmapReply(QDeclarativeImageReader *reader, const QUrl &url, int req_width, int req_height);
- Q_DISABLE_COPY(QDeclarativePixmapReply)
- Q_DECLARE_PRIVATE(QDeclarativePixmapReply)
- friend class QDeclarativeImageRequestHandler;
- friend class QDeclarativeImageReader;
- friend class QDeclarativePixmapCache;
+ Q_DISABLE_COPY(QDeclarativePixmap);
+ QDeclarativePixmapData *d;
};
-class Q_DECLARATIVE_EXPORT QDeclarativePixmapCache
+inline QDeclarativePixmap::operator const QPixmap &() const
{
- Q_DECLARE_TR_FUNCTIONS(QDeclarativePixmapCache)
-public:
- static QDeclarativePixmapReply::Status get(const QUrl& url, QPixmap *pixmap, QString *errorString, QSize *impsize=0, bool async=false, int req_width=0, int req_height=0);
- static QDeclarativePixmapReply *request(QDeclarativeEngine *, const QUrl& url, int req_width=0, int req_height=0);
- static void cancel(const QUrl& url, QObject *obj);
- static int pendingRequests();
-};
-
-
+ return pixmap();
+}
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp
index 6b6df4d..5d47c30 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation.cpp
+++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp
@@ -307,7 +307,7 @@ Rectangle {
set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity
of 0.5 will take 2000 ms to complete.
- \sa SpringFollow, {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent)
diff --git a/src/declarative/util/qdeclarativesmoothedfollow.cpp b/src/declarative/util/qdeclarativesmoothedfollow.cpp
deleted file mode 100644
index f70df9d..0000000
--- a/src/declarative/util/qdeclarativesmoothedfollow.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 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 "qdeclarativesmoothedfollow_p.h"
-#include "qdeclarativesmoothedanimation_p_p.h"
-
-#include <private/qobject_p.h>
-#include <QtCore/qnumeric.h>
-
-#include "qdeclarativeglobal_p.h"
-
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeSmoothedFollowPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeSmoothedFollow)
-public:
- QDeclarativeSmoothedFollowPrivate();
-
- bool enabled;
- QSmoothedAnimation *anim;
-};
-
-/*!
- \qmlclass SmoothedFollow QDeclarativeSmoothedFollow
- \since 4.7
- \inherits NumberAnimation
- \brief The SmoothedFollow element allows a property to smoothly track a value.
-
- The SmoothedFollow animates a property's value to a set target value
- using an ease in/out quad easing curve. If the animation is restarted
- with a different target value, the easing curves used to animate to the old
- and the new target values are smoothly spliced together to avoid any obvious
- visual glitches by maintaining the current velocity.
-
- The property animation is configured by setting the velocity at which the
- animation should occur, or the duration that the animation should take.
- If both a velocity and a duration are specified, the one that results in
- the quickest animation is chosen for each change in the target value.
-
- For example, animating from 0 to 800 will take 4 seconds if a velocity
- of 200 is set, will take 8 seconds with a duration of 8000 set, and will
- take 4 seconds with both a velocity of 200 and a duration of 8000 set.
- Animating from 0 to 20000 will take 10 seconds if a velocity of 200 is set,
- will take 8 seconds with a duration of 8000 set, and will take 8 seconds
- with both a velocity of 200 and a duration of 8000 set.
-
- The follow example shows one rectangle tracking the position of another.
-\code
-import Qt 4.7
-
-Rectangle {
- width: 800; height: 600; color: "blue"
-
- Rectangle {
- color: "green"
- width: 60; height: 60;
- SmoothedFollow on x { to: rect1.x - 5; velocity: 200 }
- SmoothedFollow on y { to: rect1.y - 5; velocity: 200 }
- }
-
- Rectangle {
- id: rect1
- color: "red"
- width: 50; height: 50;
- }
-
- focus: true
- Keys.onRightPressed: rect1.x = rect1.x + 100
- Keys.onLeftPressed: rect1.x = rect1.x - 100
- Keys.onUpPressed: rect1.y = rect1.y - 100
- Keys.onDownPressed: rect1.y = rect1.y + 100
-}
-\endcode
-
- The default velocity of SmoothedFollow is 200 units/second. Note that if the range of the
- value being animated is small, then the velocity will need to be adjusted
- appropriately. For example, the opacity of an item ranges from 0 - 1.0.
- To enable a smooth animation in this range the velocity will need to be
- set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity
- of 0.5 will take 2000 ms to complete.
-
- \sa SpringFollow
-*/
-
-QDeclarativeSmoothedFollow::QDeclarativeSmoothedFollow(QObject *parent)
- : QObject(*(new QDeclarativeSmoothedFollowPrivate), parent)
-{
-}
-
-QDeclarativeSmoothedFollow::~QDeclarativeSmoothedFollow()
-{
-}
-
-QDeclarativeSmoothedFollowPrivate::QDeclarativeSmoothedFollowPrivate()
- : enabled(true), anim(new QSmoothedAnimation)
-{
- Q_Q(QDeclarativeSmoothedFollow);
- QDeclarative_setParent_noEvent(anim, q);
-}
-
-/*!
- \qmlproperty enumeration SmoothedFollow::reversingMode
-
- Sets how the SmoothedFollow behaves if an animation direction is reversed.
-
- If reversing mode is \c SmoothedFollow.Eased, the animation will smoothly decelerate, and
- then reverse direction. If the reversing mode is \c SmoothedFollow.Immediate, the
- animation will immediately begin accelerating in the reverse direction,
- begining with a velocity of 0. If the reversing mode is \c SmoothedFollow.Sync, the
- property is immediately set to the target value.
-*/
-QDeclarativeSmoothedFollow::ReversingMode QDeclarativeSmoothedFollow::reversingMode() const
-{
- Q_D(const QDeclarativeSmoothedFollow);
- return (ReversingMode) d->anim->reversingMode;
-}
-
-void QDeclarativeSmoothedFollow::setReversingMode(ReversingMode m)
-{
- Q_D(QDeclarativeSmoothedFollow);
- if (d->anim->reversingMode == (QDeclarativeSmoothedAnimation::ReversingMode) m)
- return;
-
- d->anim->reversingMode = (QDeclarativeSmoothedAnimation::ReversingMode) m;
- emit reversingModeChanged();
-}
-
-/*!
- \qmlproperty int SmoothedFollow::duration
-
- This property holds the animation duration, in msecs, used when tracking the source.
-
- Setting this to -1 (the default) disables the duration value.
-*/
-int QDeclarativeSmoothedFollow::duration() const
-{
- Q_D(const QDeclarativeSmoothedFollow);
- return d->anim->userDuration;
-}
-
-void QDeclarativeSmoothedFollow::setDuration(int duration)
-{
- Q_D(QDeclarativeSmoothedFollow);
- if (duration == d->anim->duration())
- return;
-
- d->anim->userDuration = duration;
- emit durationChanged();
-}
-
-qreal QDeclarativeSmoothedFollow::velocity() const
-{
- Q_D(const QDeclarativeSmoothedFollow);
- return d->anim->velocity;
-}
-
-/*!
- \qmlproperty real SmoothedFollow::velocity
-
- This property holds the average velocity allowed when tracking the 'to' value.
-
- The default velocity of SmoothedFollow is 200 units/second.
-
- Setting this to -1 disables the velocity value.
-*/
-void QDeclarativeSmoothedFollow::setVelocity(qreal v)
-{
- Q_D(QDeclarativeSmoothedFollow);
- if (d->anim->velocity == v)
- return;
-
- d->anim->velocity = v;
- emit velocityChanged();
-}
-
-/*!
- \qmlproperty int SmoothedFollow::maximumEasingTime
-
- This property specifies the maximum time, in msecs, an "eases" during the follow should take.
- Setting this property causes the velocity to "level out" after at a time. Setting
- a negative value reverts to the normal mode of easing over the entire animation
- duration.
-
- The default value is -1.
-*/
-int QDeclarativeSmoothedFollow::maximumEasingTime() const
-{
- Q_D(const QDeclarativeSmoothedFollow);
- return d->anim->maximumEasingTime;
-}
-
-void QDeclarativeSmoothedFollow::setMaximumEasingTime(int v)
-{
- Q_D(QDeclarativeSmoothedFollow);
- d->anim->maximumEasingTime = v;
- emit maximumEasingTimeChanged();
-}
-
-/*!
- \qmlproperty real SmoothedFollow::to
- This property holds the ending value.
- If not set, then the value defined in the end state of the transition or Behavior.
-*/
-qreal QDeclarativeSmoothedFollow::to() const
-{
- Q_D(const QDeclarativeSmoothedFollow);
- return d->anim->to;
-}
-
-void QDeclarativeSmoothedFollow::setTo(qreal t)
-{
- Q_D(QDeclarativeSmoothedFollow);
-
- if (qIsNaN(t))
- return;
-
- if (d->anim->to == t)
- return;
-
- d->anim->to = t;
-
- if (d->enabled)
- d->anim->restart();
-}
-
-/*!
- \qmlproperty bool SmoothedFollow::enabled
- This property whether this animation should automatically restart when
- the 'to' property is upated.
-
- The default value of this property is 'true'.
-*/
-bool QDeclarativeSmoothedFollow::enabled() const
-{
- Q_D(const QDeclarativeSmoothedFollow);
- return d->enabled;
-}
-
-void QDeclarativeSmoothedFollow::setEnabled(bool e)
-{
- Q_D(QDeclarativeSmoothedFollow);
- if (d->enabled == e)
- return;
- d->enabled = e;
-
- if (d->enabled)
- d->anim->restart();
- else
- d->anim->stop();
- emit enabledChanged();
-}
-
-void QDeclarativeSmoothedFollow::setTarget(const QDeclarativeProperty &t)
-{
- Q_D(QDeclarativeSmoothedFollow);
- d->anim->target = t;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativesmoothedfollow_p.h b/src/declarative/util/qdeclarativesmoothedfollow_p.h
deleted file mode 100644
index f852311..0000000
--- a/src/declarative/util/qdeclarativesmoothedfollow_p.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 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 QDECLARATIVESMOOTHEDFOLLOW_H
-#define QDECLARATIVESMOOTHEDFOLLOW_H
-
-#include <qdeclarative.h>
-#include <qdeclarativepropertyvaluesource.h>
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeProperty;
-class QDeclarativeSmoothedFollowPrivate;
-class Q_AUTOTEST_EXPORT QDeclarativeSmoothedFollow : public QObject,
- public QDeclarativePropertyValueSource
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QDeclarativeSmoothedFollow)
- Q_INTERFACES(QDeclarativePropertyValueSource)
- Q_ENUMS(ReversingMode)
-
- Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
- Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
- Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
- Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged)
- Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged)
- Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
-
-public:
- enum ReversingMode { Eased, Immediate, Sync };
-
- QDeclarativeSmoothedFollow(QObject *parent = 0);
- ~QDeclarativeSmoothedFollow();
-
- qreal to() const;
- void setTo(qreal);
-
- ReversingMode reversingMode() const;
- void setReversingMode(ReversingMode);
-
- int duration() const;
- void setDuration(int);
-
- qreal velocity() const;
- void setVelocity(qreal);
-
- int maximumEasingTime() const;
- void setMaximumEasingTime(int);
-
- bool enabled() const;
- void setEnabled(bool);
-
- virtual void setTarget(const QDeclarativeProperty &);
-
-Q_SIGNALS:
- void velocityChanged();
- void durationChanged();
- void reversingModeChanged();
- void maximumEasingTimeChanged();
- void enabledChanged();
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QDeclarativeSmoothedFollow)
-
-QT_END_HEADER
-
-#endif // QDECLARATIVESMOOTHEDFOLLOW_H
diff --git a/src/declarative/util/qdeclarativespringfollow.cpp b/src/declarative/util/qdeclarativespringanimation.cpp
index aae66ac..4cf2fc0 100644
--- a/src/declarative/util/qdeclarativespringfollow.cpp
+++ b/src/declarative/util/qdeclarativespringanimation.cpp
@@ -39,9 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativespringfollow_p.h"
+#include "private/qdeclarativespringanimation_p.h"
#include "private/qdeclarativeanimation_p_p.h"
+#include <qdeclarativeproperty_p.h>
#include <QtCore/qdebug.h>
@@ -54,18 +55,20 @@ QT_BEGIN_NAMESPACE
-class QDeclarativeSpringFollowPrivate : public QObjectPrivate
+class QDeclarativeSpringAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
{
- Q_DECLARE_PUBLIC(QDeclarativeSpringFollow)
+ Q_DECLARE_PUBLIC(QDeclarativeSpringAnimation)
public:
- QDeclarativeSpringFollowPrivate()
- : currentValue(0), to(0), maxVelocity(0), lastTime(0)
+ QDeclarativeSpringAnimationPrivate()
+ : currentValue(0), to(0), from(0), maxVelocity(0), lastTime(0)
, mass(1.0), spring(0.), damping(0.), velocity(0), epsilon(0.01)
- , modulus(0.0), useMass(false), haveModulus(false), enabled(true), mode(Track), clock(this) {}
+ , modulus(0.0), useMass(false), haveModulus(false), enabled(true)
+ , fromDefined(false), toDefined(false)
+ , mode(Track), clock(this) {}
- QDeclarativeProperty property;
qreal currentValue;
qreal to;
+ qreal from;
qreal maxVelocity;
qreal velocityms;
int lastTime;
@@ -79,6 +82,8 @@ public:
bool useMass : 1;
bool haveModulus : 1;
bool enabled : 1;
+ bool fromDefined : 1;
+ bool toDefined : 1;
enum Mode {
Track,
@@ -89,20 +94,24 @@ public:
void tick(int);
void updateMode();
- void start();
- void stop();
- QTickAnimationProxy<QDeclarativeSpringFollowPrivate, &QDeclarativeSpringFollowPrivate::tick> clock;
+ QTickAnimationProxy<QDeclarativeSpringAnimationPrivate, &QDeclarativeSpringAnimationPrivate::tick> clock;
};
-void QDeclarativeSpringFollowPrivate::tick(int time)
+void QDeclarativeSpringAnimationPrivate::tick(int time)
{
- Q_Q(QDeclarativeSpringFollow);
+ if (mode == Track) {
+ clock.stop();
+ return;
+ }
int elapsed = time - lastTime;
if (!elapsed)
return;
qreal srcVal = to;
+
+ bool stop = false;
+
if (haveModulus) {
currentValue = fmod(currentValue, modulus);
srcVal = fmod(srcVal, modulus);
@@ -142,7 +151,7 @@ void QDeclarativeSpringFollowPrivate::tick(int time)
if (qAbs(velocity) < epsilon && qAbs(srcVal - currentValue) < epsilon) {
velocity = 0.0;
currentValue = srcVal;
- clock.stop();
+ stop = true;
}
lastTime = time - (elapsed - count * 16);
} else {
@@ -160,7 +169,7 @@ void QDeclarativeSpringFollowPrivate::tick(int time)
currentValue = fmod(currentValue, modulus);
if (currentValue > to) {
currentValue = to;
- clock.stop();
+ stop = true;
}
} else {
currentValue -= moveBy;
@@ -168,18 +177,23 @@ void QDeclarativeSpringFollowPrivate::tick(int time)
currentValue = fmod(currentValue, modulus) + modulus;
if (currentValue < to) {
currentValue = to;
- clock.stop();
+ stop = true;
}
}
lastTime = time;
}
- property.write(currentValue);
- emit q->valueChanged(currentValue);
- if (clock.state() != QAbstractAnimation::Running)
- emit q->syncChanged();
+
+ qreal old_to = to;
+
+ QDeclarativePropertyPrivate::write(defaultProperty, currentValue,
+ QDeclarativePropertyPrivate::BypassInterceptor |
+ QDeclarativePropertyPrivate::DontRemoveBinding);
+
+ if (stop && old_to == to) // do not stop if we got restarted
+ clock.stop();
}
-void QDeclarativeSpringFollowPrivate::updateMode()
+void QDeclarativeSpringAnimationPrivate::updateMode()
{
if (spring == 0. && maxVelocity == 0.)
mode = Track;
@@ -189,121 +203,105 @@ void QDeclarativeSpringFollowPrivate::updateMode()
mode = Velocity;
}
-void QDeclarativeSpringFollowPrivate::start()
-{
- if (!enabled)
- return;
+/*!
+ \qmlclass SpringAnimation QDeclarativeSpringAnimation
+ \since 4.7
- Q_Q(QDeclarativeSpringFollow);
- if (mode == QDeclarativeSpringFollowPrivate::Track) {
- currentValue = to;
- property.write(currentValue);
- } else if (to != currentValue && clock.state() != QAbstractAnimation::Running) {
- lastTime = 0;
- currentValue = property.read().toReal();
- clock.start(); // infinity??
- emit q->syncChanged();
- }
-}
+ \brief The SpringAnimation element allows a property to track a value in a spring-like motion
+
+ SpringAnimation mimics the oscillatory behavior of a spring, with the appropriate \l spring constant to
+ control the acceleration and the \l damping to control how quickly the effect dies away.
+
+ You can also limit the maximum \l velocity of the animation.
-void QDeclarativeSpringFollowPrivate::stop()
-{
- clock.stop();
-}
-/*!
- \qmlclass SpringFollow QDeclarativeSpringFollow
- \since 4.7
- \brief The SpringFollow element allows a property to track a value.
-
- In example below, \e rect2 will follow \e rect1 moving with a velocity of up to 200:
- \code
- Rectangle {
- id: rect1
- width: 20; height: 20
- color: "#00ff00"
- y: 200 // initial value
- SequentialAnimation on y {
- loops: Animation.Infinite
- NumberAnimation {
- to: 200
- easing.type: Easing.OutBounce
- easing.amplitude: 100
- duration: 2000
- }
- PauseAnimation { duration: 1000 }
- }
- }
- Rectangle {
- id: rect2
- x: rect1.width
- width: 20; height: 20
- color: "#ff0000"
- SpringFollow on y { to: rect1.y; velocity: 200 }
- }
- \endcode
*/
-QDeclarativeSpringFollow::QDeclarativeSpringFollow(QObject *parent)
-: QObject(*(new QDeclarativeSpringFollowPrivate),parent)
+QDeclarativeSpringAnimation::QDeclarativeSpringAnimation(QObject *parent)
+: QDeclarativeAbstractAnimation(*(new QDeclarativeSpringAnimationPrivate),parent)
{
}
-QDeclarativeSpringFollow::~QDeclarativeSpringFollow()
+QDeclarativeSpringAnimation::~QDeclarativeSpringAnimation()
{
}
-void QDeclarativeSpringFollow::setTarget(const QDeclarativeProperty &property)
+void QDeclarativeSpringAnimation::setTarget(const QDeclarativeProperty &property)
{
- Q_D(QDeclarativeSpringFollow);
- d->property = property;
+ Q_D(QDeclarativeSpringAnimation);
+ d->defaultProperty = property;
d->currentValue = property.read().toReal();
+ if (!d->avoidPropertyValueSourceStart) {
+ setRunning(true);
+ }
}
-qreal QDeclarativeSpringFollow::to() const
+qreal QDeclarativeSpringAnimation::to() const
{
- Q_D(const QDeclarativeSpringFollow);
- return d->to;
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->toDefined ? d->to : 0;
}
/*!
- \qmlproperty real SpringFollow::to
- This property holds the target value which will be tracked.
-
- Bind to a property in order to track its changes.
+ \qmlproperty real SpringAnimation::to
*/
-void QDeclarativeSpringFollow::setTo(qreal value)
+void QDeclarativeSpringAnimation::setTo(qreal value)
{
- Q_D(QDeclarativeSpringFollow);
- if (d->clock.state() == QAbstractAnimation::Running && d->to == value)
+ Q_D(QDeclarativeSpringAnimation);
+ if (d->to == value)
return;
d->to = value;
- d->start();
+ d->toDefined = true;
+ d->lastTime = 0;
+ emit toChanged(value);
+}
+
+qreal QDeclarativeSpringAnimation::from() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->fromDefined ? d->from : 0;
}
/*!
- \qmlproperty real SpringFollow::velocity
+ \qmlproperty real SpringAnimation::from
+*/
+
+void QDeclarativeSpringAnimation::setFrom(qreal value)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ if (d->from == value)
+ return;
+
+ d->currentValue = d->from = value;
+ d->fromDefined = true;
+ d->lastTime = 0;
+ emit fromChanged(value);
+}
+
+
+/*!
+ \qmlproperty real SpringAnimation::velocity
This property holds the maximum velocity allowed when tracking the source.
*/
-qreal QDeclarativeSpringFollow::velocity() const
+qreal QDeclarativeSpringAnimation::velocity() const
{
- Q_D(const QDeclarativeSpringFollow);
+ Q_D(const QDeclarativeSpringAnimation);
return d->maxVelocity;
}
-void QDeclarativeSpringFollow::setVelocity(qreal velocity)
+void QDeclarativeSpringAnimation::setVelocity(qreal velocity)
{
- Q_D(QDeclarativeSpringFollow);
+ Q_D(QDeclarativeSpringAnimation);
d->maxVelocity = velocity;
d->velocityms = velocity / 1000.0;
d->updateMode();
}
/*!
- \qmlproperty real SpringFollow::spring
+ \qmlproperty real SpringAnimation::spring
This property holds the spring constant
The spring constant describes how strongly the target is pulled towards the
@@ -312,35 +310,35 @@ void QDeclarativeSpringFollow::setVelocity(qreal velocity)
When a spring constant is set and the velocity property is greater than 0,
velocity limits the maximum speed.
*/
-qreal QDeclarativeSpringFollow::spring() const
+qreal QDeclarativeSpringAnimation::spring() const
{
- Q_D(const QDeclarativeSpringFollow);
+ Q_D(const QDeclarativeSpringAnimation);
return d->spring;
}
-void QDeclarativeSpringFollow::setSpring(qreal spring)
+void QDeclarativeSpringAnimation::setSpring(qreal spring)
{
- Q_D(QDeclarativeSpringFollow);
+ Q_D(QDeclarativeSpringAnimation);
d->spring = spring;
d->updateMode();
}
/*!
- \qmlproperty real SpringFollow::damping
+ \qmlproperty real SpringAnimation::damping
This property holds the spring damping constant
The damping constant describes how quickly a sprung follower comes to rest.
Useful range is 0 - 1.0
*/
-qreal QDeclarativeSpringFollow::damping() const
+qreal QDeclarativeSpringAnimation::damping() const
{
- Q_D(const QDeclarativeSpringFollow);
+ Q_D(const QDeclarativeSpringAnimation);
return d->damping;
}
-void QDeclarativeSpringFollow::setDamping(qreal damping)
+void QDeclarativeSpringAnimation::setDamping(qreal damping)
{
- Q_D(QDeclarativeSpringFollow);
+ Q_D(QDeclarativeSpringAnimation);
if (damping > 1.)
damping = 1.;
@@ -349,7 +347,7 @@ void QDeclarativeSpringFollow::setDamping(qreal damping)
/*!
- \qmlproperty real SpringFollow::epsilon
+ \qmlproperty real SpringAnimation::epsilon
This property holds the spring epsilon
The epsilon is the rate and amount of change in the value which is close enough
@@ -358,34 +356,34 @@ void QDeclarativeSpringFollow::setDamping(qreal damping)
The default is 0.01. Tuning this value can provide small performance improvements.
*/
-qreal QDeclarativeSpringFollow::epsilon() const
+qreal QDeclarativeSpringAnimation::epsilon() const
{
- Q_D(const QDeclarativeSpringFollow);
+ Q_D(const QDeclarativeSpringAnimation);
return d->epsilon;
}
-void QDeclarativeSpringFollow::setEpsilon(qreal epsilon)
+void QDeclarativeSpringAnimation::setEpsilon(qreal epsilon)
{
- Q_D(QDeclarativeSpringFollow);
+ Q_D(QDeclarativeSpringAnimation);
d->epsilon = epsilon;
}
/*!
- \qmlproperty real SpringFollow::modulus
+ \qmlproperty real SpringAnimation::modulus
This property holds the modulus value.
Setting a \a modulus forces the target value to "wrap around" at the modulus.
For example, setting the modulus to 360 will cause a value of 370 to wrap around to 10.
*/
-qreal QDeclarativeSpringFollow::modulus() const
+qreal QDeclarativeSpringAnimation::modulus() const
{
- Q_D(const QDeclarativeSpringFollow);
+ Q_D(const QDeclarativeSpringAnimation);
return d->modulus;
}
-void QDeclarativeSpringFollow::setModulus(qreal modulus)
+void QDeclarativeSpringAnimation::setModulus(qreal modulus)
{
- Q_D(QDeclarativeSpringFollow);
+ Q_D(QDeclarativeSpringAnimation);
if (d->modulus != modulus) {
d->haveModulus = modulus != 0.0;
d->modulus = modulus;
@@ -394,21 +392,21 @@ void QDeclarativeSpringFollow::setModulus(qreal modulus)
}
/*!
- \qmlproperty real SpringFollow::mass
+ \qmlproperty real SpringAnimation::mass
This property holds the "mass" of the property being moved.
mass is 1.0 by default. Setting a different mass changes the dynamics of
a \l spring follow.
*/
-qreal QDeclarativeSpringFollow::mass() const
+qreal QDeclarativeSpringAnimation::mass() const
{
- Q_D(const QDeclarativeSpringFollow);
+ Q_D(const QDeclarativeSpringAnimation);
return d->mass;
}
-void QDeclarativeSpringFollow::setMass(qreal mass)
+void QDeclarativeSpringAnimation::setMass(qreal mass)
{
- Q_D(QDeclarativeSpringFollow);
+ Q_D(QDeclarativeSpringAnimation);
if (d->mass != mass && mass > 0.0) {
d->useMass = mass != 1.0;
d->mass = mass;
@@ -416,49 +414,33 @@ void QDeclarativeSpringFollow::setMass(qreal mass)
}
}
-/*!
- \qmlproperty bool SpringFollow::enabled
- This property holds whether the target will track the source.
-
- The default value of this property is 'true'.
-*/
-bool QDeclarativeSpringFollow::enabled() const
-{
- Q_D(const QDeclarativeSpringFollow);
- return d->enabled;
-}
-
-void QDeclarativeSpringFollow::setEnabled(bool enabled)
+void QDeclarativeSpringAnimation::transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction)
{
- Q_D(QDeclarativeSpringFollow);
- d->enabled = enabled;
- if (enabled)
- d->start();
- else
- d->stop();
+ Q_D(QDeclarativeSpringAnimation);
+ Q_UNUSED(direction);
+
+ if (d->clock.state() != QAbstractAnimation::Running)
+ d->lastTime = 0;
+
+ if (!actions.isEmpty()) {
+ for (int i = 0; i < actions.size(); ++i) {
+ if (!d->toDefined)
+ d->to = actions.at(i).toValue.toReal();
+ if (!d->fromDefined)
+ d->currentValue = actions.at(i).fromValue.toReal();
+ if (d->mode != QDeclarativeSpringAnimationPrivate::Track)
+ modified << d->defaultProperty;
+ }
+ }
}
-/*!
- \qmlproperty bool SpringFollow::inSync
- This property is true when target is equal to the source; otherwise
- false. If inSync is true the target is not being animated.
- If \l enabled is false then inSync will also be false.
-*/
-bool QDeclarativeSpringFollow::inSync() const
-{
- Q_D(const QDeclarativeSpringFollow);
- return d->enabled && d->clock.state() != QAbstractAnimation::Running;
-}
-
-/*!
- \qmlproperty real SpringFollow::value
- The current value.
-*/
-qreal QDeclarativeSpringFollow::value() const
+QAbstractAnimation *QDeclarativeSpringAnimation::qtAnimation()
{
- Q_D(const QDeclarativeSpringFollow);
- return d->currentValue;
+ Q_D(QDeclarativeSpringAnimation);
+ return &d->clock;
}
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativespringfollow_p.h b/src/declarative/util/qdeclarativespringanimation_p.h
index b6277c3..6f574ef 100644
--- a/src/declarative/util/qdeclarativespringfollow_p.h
+++ b/src/declarative/util/qdeclarativespringanimation_p.h
@@ -39,11 +39,13 @@
**
****************************************************************************/
-#ifndef QDECLARATIVESMOOTHFOLLOW_H
-#define QDECLARATIVESMOOTHFOLLOW_H
+#ifndef QDECLARATIVESPRINGANIMATION_H
+#define QDECLARATIVESPRINGANIMATION_H
-#include <qdeclarativepropertyvaluesource.h>
#include <qdeclarative.h>
+#include "private/qdeclarativeanimation_p.h"
+
+#include <QtCore/qobject.h>
QT_BEGIN_HEADER
@@ -51,34 +53,34 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QDeclarativeSpringFollowPrivate;
-class Q_AUTOTEST_EXPORT QDeclarativeSpringFollow : public QObject,
- public QDeclarativePropertyValueSource
+class QDeclarativeSpringAnimationPrivate;
+class Q_AUTOTEST_EXPORT QDeclarativeSpringAnimation : public QDeclarativeAbstractAnimation
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QDeclarativeSpringFollow)
+ Q_DECLARE_PRIVATE(QDeclarativeSpringAnimation)
Q_INTERFACES(QDeclarativePropertyValueSource)
- Q_PROPERTY(qreal to READ to WRITE setTo)
+ Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
+ Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity)
Q_PROPERTY(qreal spring READ spring WRITE setSpring)
Q_PROPERTY(qreal damping READ damping WRITE setDamping)
Q_PROPERTY(qreal epsilon READ epsilon WRITE setEpsilon)
- Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
- Q_PROPERTY(qreal value READ value NOTIFY valueChanged)
Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged)
Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged)
- Q_PROPERTY(bool inSync READ inSync NOTIFY syncChanged)
public:
- QDeclarativeSpringFollow(QObject *parent=0);
- ~QDeclarativeSpringFollow();
+ QDeclarativeSpringAnimation(QObject *parent=0);
+ ~QDeclarativeSpringAnimation();
virtual void setTarget(const QDeclarativeProperty &);
qreal to() const;
void setTo(qreal value);
+ qreal from() const;
+ void setFrom(qreal value);
+
qreal velocity() const;
void setVelocity(qreal velocity);
@@ -100,12 +102,16 @@ public:
bool enabled() const;
void setEnabled(bool enabled);
- bool inSync() const;
+ virtual void transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction);
- qreal value() const;
+protected:
+ virtual QAbstractAnimation *qtAnimation();
Q_SIGNALS:
- void valueChanged(qreal);
+ void toChanged(qreal);
+ void fromChanged(qreal);
void modulusChanged();
void massChanged();
void syncChanged();
@@ -113,8 +119,8 @@ Q_SIGNALS:
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QDeclarativeSpringFollow)
+QML_DECLARE_TYPE(QDeclarativeSpringAnimation)
QT_END_HEADER
-#endif // QDECLARATIVESMOOTHFOLLOW_H
+#endif // QDECLARATIVESPRINGANIMATION_H
diff --git a/src/declarative/util/qdeclarativestyledtext.cpp b/src/declarative/util/qdeclarativestyledtext.cpp
index babd71b..91566bc 100644
--- a/src/declarative/util/qdeclarativestyledtext.cpp
+++ b/src/declarative/util/qdeclarativestyledtext.cpp
@@ -152,8 +152,6 @@ void QDeclarativeStyledTextPrivate::parse()
QTextCharFormat format;
if (formatStack.count())
format = formatStack.top();
- else
- format.setFont(baseFont);
if (parseTag(ch, text, drawText, format))
formatStack.push(format);
}
@@ -198,8 +196,10 @@ bool QDeclarativeStyledTextPrivate::parseTag(const QChar *&ch, const QString &te
if (char0 == QLatin1Char('b')) {
if (tagLength == 1)
format.setFontWeight(QFont::Bold);
- else if (tagLength == 2 && tag.at(1) == QLatin1Char('r'))
+ else if (tagLength == 2 && tag.at(1) == QLatin1Char('r')) {
textOut.append(QChar(QChar::LineSeparator));
+ return false;
+ }
} else if (char0 == QLatin1Char('i')) {
if (tagLength == 1)
format.setFontItalic(true);
diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp
index 3cf07a7..c5bfebd 100644
--- a/src/declarative/util/qdeclarativeutilmodule.cpp
+++ b/src/declarative/util/qdeclarativeutilmodule.cpp
@@ -46,7 +46,6 @@
#include "private/qdeclarativebind_p.h"
#include "private/qdeclarativeconnections_p.h"
#include "private/qdeclarativesmoothedanimation_p.h"
-#include "private/qdeclarativesmoothedfollow_p.h"
#include "private/qdeclarativefontloader_p.h"
#include "private/qdeclarativelistaccessor_p.h"
#include "private/qdeclarativelistmodel_p.h"
@@ -56,7 +55,7 @@
#include "private/qdeclarativepixmapcache_p.h"
#include "private/qdeclarativepropertychanges_p.h"
#include "qdeclarativepropertymap.h"
-#include "private/qdeclarativespringfollow_p.h"
+#include "private/qdeclarativespringanimation_p.h"
#include "private/qdeclarativestategroup_p.h"
#include "private/qdeclarativestateoperations_p.h"
#include "private/qdeclarativestate_p.h"
@@ -83,7 +82,6 @@ void QDeclarativeUtilModule::defineModule()
qmlRegisterType<QDeclarativeColorAnimation>("Qt",4,7,"ColorAnimation");
qmlRegisterType<QDeclarativeConnections>("Qt",4,7,"Connections");
qmlRegisterType<QDeclarativeSmoothedAnimation>("Qt",4,7,"SmoothedAnimation");
- qmlRegisterType<QDeclarativeSmoothedFollow>("Qt",4,7,"SmoothedFollow");
qmlRegisterType<QDeclarativeFontLoader>("Qt",4,7,"FontLoader");
qmlRegisterType<QDeclarativeListElement>("Qt",4,7,"ListElement");
qmlRegisterType<QDeclarativeNumberAnimation>("Qt",4,7,"NumberAnimation");
@@ -97,7 +95,7 @@ void QDeclarativeUtilModule::defineModule()
qmlRegisterType<QDeclarativeRotationAnimation>("Qt",4,7,"RotationAnimation");
qmlRegisterType<QDeclarativeScriptAction>("Qt",4,7,"ScriptAction");
qmlRegisterType<QDeclarativeSequentialAnimation>("Qt",4,7,"SequentialAnimation");
- qmlRegisterType<QDeclarativeSpringFollow>("Qt",4,7,"SpringFollow");
+ qmlRegisterType<QDeclarativeSpringAnimation>("Qt",4,7,"SpringAnimation");
qmlRegisterType<QDeclarativeStateChangeScript>("Qt",4,7,"StateChangeScript");
qmlRegisterType<QDeclarativeStateGroup>("Qt",4,7,"StateGroup");
qmlRegisterType<QDeclarativeState>("Qt",4,7,"State");
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index 0414e65..496f2ad 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -194,45 +194,46 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem,
\since 4.7
\brief The QDeclarativeView class provides a widget for displaying a Qt Declarative user interface.
- Any QGraphicsObject or QDeclarativeItem
- created via QML can be placed on a standard QGraphicsScene and viewed with a standard
- QGraphicsView.
+ QDeclarativeItem objects can be placed on a standard QGraphicsScene and
+ displayed with QGraphicsView. QDeclarativeView is a QGraphicsView subclass
+ provided as a convenience for displaying QML files, and connecting between
+ QML and C++ Qt objects.
- QDeclarativeView is a QGraphicsView subclass provided as a convenience for displaying QML
- files, and connecting between QML and C++ Qt objects.
-
- QDeclarativeView performs the following functions:
+ QDeclarativeView provides:
\list
- \o Manages QDeclarativeComponent loading and object creation.
- \o Initializes QGraphicsView for optimal performance with QML:
+ \o Management of QDeclarativeComponent loading and object creation
+ \o Initialization of QGraphicsView for optimal performance with QML using these settings:
\list
- \o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState);
- \o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
- \o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex);
+ \o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState)
+ \o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate)
+ \o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex)
\endlist
- \o Initializes QGraphicsView for QML key handling:
+ \o Initialization of QGraphicsView for QML key handling using these settings:
\list
- \o QGraphicsView::viewport()->setFocusPolicy(Qt::NoFocus);
- \o QGraphicsView::setFocusPolicy(Qt::StrongFocus);
- \o QGraphicsScene::setStickyFocus(true);
+ \o QGraphicsView::viewport()->setFocusPolicy(Qt::NoFocus)
+ \o QGraphicsView::setFocusPolicy(Qt::StrongFocus)
+ \o QGraphicsScene::setStickyFocus(true)
\endlist
\endlist
Typical usage:
- \code
- ...
- QDeclarativeView *view = new QDeclarativeView(this);
- vbox->addWidget(view);
- QUrl url = QUrl::fromLocalFile(fileName);
- view->setSource(url);
+ \code
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
view->show();
\endcode
+ Since QDeclarativeView is a QWidget-based class, it can be used to
+ display QML interfaces within QWidget-based GUI applications that do not
+ use the Graphics View framework.
+
To receive errors related to loading and executing QML with QDeclarativeView,
you can connect to the statusChanged() signal and monitor for QDeclarativeView::Error.
The errors are available via QDeclarativeView::errors().
+
+ \sa {Integrating QML with existing Qt UI code}, {Using QML in C++ Applications}
*/
@@ -611,7 +612,7 @@ void QDeclarativeView::timerEvent(QTimerEvent* e)
}
}
-/*! \reimp */
+/*! \internal */
bool QDeclarativeView::eventFilter(QObject *watched, QEvent *e)
{
Q_D(QDeclarativeView);
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 8ed34ab..05a8501 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -667,7 +667,7 @@ QString QDeclarativeXmlListModel::toString(int role) const
\qmlproperty url XmlListModel::source
The location of the XML data source.
- If both source and xml are set, xml will be used.
+ If both \c source and \l xml are set, \l xml is used.
*/
QUrl QDeclarativeXmlListModel::source() const
{
@@ -692,7 +692,7 @@ void QDeclarativeXmlListModel::setSource(const QUrl &src)
The text is assumed to be UTF-8 encoded.
- If both \l source and \c xml are set, \c xml will be used.
+ If both \l source and \c xml are set, \c xml is used.
*/
QString QDeclarativeXmlListModel::xml() const
{
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index 04cfc68..fd57144 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -7,9 +7,8 @@ SOURCES += \
$$PWD/qdeclarativepackage.cpp \
$$PWD/qdeclarativeanimation.cpp \
$$PWD/qdeclarativesystempalette.cpp \
- $$PWD/qdeclarativespringfollow.cpp \
+ $$PWD/qdeclarativespringanimation.cpp \
$$PWD/qdeclarativesmoothedanimation.cpp \
- $$PWD/qdeclarativesmoothedfollow.cpp \
$$PWD/qdeclarativestate.cpp\
$$PWD/qdeclarativetransitionmanager.cpp \
$$PWD/qdeclarativestateoperations.cpp \
@@ -38,9 +37,8 @@ HEADERS += \
$$PWD/qdeclarativeanimation_p.h \
$$PWD/qdeclarativeanimation_p_p.h \
$$PWD/qdeclarativesystempalette_p.h \
- $$PWD/qdeclarativespringfollow_p.h \
+ $$PWD/qdeclarativespringanimation_p.h \
$$PWD/qdeclarativesmoothedanimation_p.h \
- $$PWD/qdeclarativesmoothedfollow_p.h \
$$PWD/qdeclarativesmoothedanimation_p_p.h \
$$PWD/qdeclarativestate_p.h\
$$PWD/qdeclarativestateoperations_p.h \