summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/QmlChanges.txt2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp100
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp35
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase.cpp65
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp34
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp38
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp150
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp26
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp52
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp4
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp37
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp2
-rw-r--r--src/declarative/qml/qdeclarativedom.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp8
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp24
-rw-r--r--src/declarative/qml/qdeclarativeextensionplugin.cpp4
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp24
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp2
-rw-r--r--src/declarative/util/qdeclarativepackage.cpp4
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp1115
-rw-r--r--src/declarative/util/qdeclarativepixmapcache_p.h85
-rw-r--r--src/declarative/util/qdeclarativestyledtext.cpp6
-rw-r--r--src/declarative/util/qdeclarativeview.cpp47
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp6
35 files changed, 1125 insertions, 787 deletions
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt
index 336fbbf..91442c1 100644
--- a/src/declarative/QmlChanges.txt
+++ b/src/declarative/QmlChanges.txt
@@ -1,5 +1,5 @@
=============================================================================
-The changes below are pre Qt 4.7.0 RC
+The changes below are pre Qt 4.7.0 beta 2
QDeclarativeView
- initialSize() function added
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index d4ca9eb..44c206b 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -94,8 +94,6 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
Q_D(QDeclarativeBorderImage);
if (d->sciReply)
d->sciReply->deleteLater();
- if (d->sciPendingPixmapCache)
- QDeclarativePixmapCache::cancel(d->sciurl, this);
}
/*!
\qmlproperty enumeration BorderImage::status
@@ -164,15 +162,6 @@ void QDeclarativeBorderImage::setSource(const QUrl &url)
d->sciReply = 0;
}
- if (d->pendingPixmapCache) {
- QDeclarativePixmapCache::cancel(d->url, this);
- d->pendingPixmapCache = false;
- }
- if (d->sciPendingPixmapCache) {
- QDeclarativePixmapCache::cancel(d->sciurl, this);
- d->sciPendingPixmapCache = false;
- }
-
d->url = url;
d->sciurl = QUrl();
emit sourceChanged(d->url);
@@ -190,7 +179,7 @@ void QDeclarativeBorderImage::load()
}
if (d->url.isEmpty()) {
- d->pix = QPixmap();
+ d->pix.clear();
d->status = Null;
setImplicitWidth(0);
setImplicitHeight(0);
@@ -224,26 +213,24 @@ void QDeclarativeBorderImage::load()
thisSciRequestFinished, Qt::DirectConnection);
}
} else {
- QSize impsize;
- QString errorString;
- QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async);
- if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) {
- QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url);
- d->pendingPixmapCache = true;
- connect(reply, SIGNAL(finished()), this, SLOT(requestFinished()));
- connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
+
+ d->pix.load(qmlEngine(this), d->url, d->async);
+
+ if (d->pix.isLoading()) {
+ d->pix.connectFinished(this, SLOT(requestFinished()));
+ d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
} else {
- //### should be unified with requestFinished
+ QSize impsize = d->pix.implicitSize();
setImplicitWidth(impsize.width());
setImplicitHeight(impsize.height());
- if (d->pix.isNull()) {
+ if (d->pix.isReady()) {
+ d->status = Ready;
+ } else {
d->status = Error;
- qmlInfo(this) << errorString;
+ qmlInfo(this) << d->pix.error();
}
- if (d->status == Loading)
- d->status = Ready;
+
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(d->progress);
@@ -343,47 +330,40 @@ void QDeclarativeBorderImage::setGridScaledImage(const QDeclarativeGridScaledIma
d->verticalTileMode = sci.verticalTileRule();
d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
- QSize impsize;
- QString errorString;
- QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->sciurl, &d->pix, &errorString, &impsize, d->async);
- if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) {
- QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->sciurl);
- d->sciPendingPixmapCache = true;
-
- static int replyDownloadProgress = -1;
- static int replyFinished = -1;
+
+ d->pix.load(qmlEngine(this), d->sciurl, d->async);
+
+ if (d->pix.isLoading()) {
static int thisRequestProgress = -1;
static int thisRequestFinished = -1;
- if (replyDownloadProgress == -1) {
- replyDownloadProgress =
- QDeclarativePixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
- replyFinished =
- QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()");
+ if (thisRequestProgress == -1) {
thisRequestProgress =
QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
thisRequestFinished =
QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
}
- QMetaObject::connect(reply, replyFinished, this,
- thisRequestFinished, Qt::DirectConnection);
- QMetaObject::connect(reply, replyDownloadProgress, this,
- thisRequestProgress, Qt::DirectConnection);
+ d->pix.connectFinished(this, thisRequestFinished);
+ d->pix.connectDownloadProgress(this, thisRequestProgress);
+
} else {
- //### should be unified with requestFinished
+
+ QSize impsize = d->pix.implicitSize();
setImplicitWidth(impsize.width());
setImplicitHeight(impsize.height());
- if (d->pix.isNull()) {
+ if (d->pix.isReady()) {
+ d->status = Ready;
+ } else {
d->status = Error;
- qmlInfo(this) << errorString;
+ qmlInfo(this) << d->pix.error();
}
- if (d->status == Loading)
- d->status = Ready;
+
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(1.0);
update();
+
}
}
}
@@ -392,27 +372,17 @@ void QDeclarativeBorderImage::requestFinished()
{
Q_D(QDeclarativeBorderImage);
- QSize impsize;
- if (d->url.path().endsWith(QLatin1String(".sci"))) {
- d->sciPendingPixmapCache = false;
- QString errorString;
- if (QDeclarativePixmapCache::get(d->sciurl, &d->pix, &errorString, &impsize, d->async) != QDeclarativePixmapReply::Ready) {
- d->status = Error;
- qmlInfo(this) << errorString;
- }
+ QSize impsize = d->pix.implicitSize();
+ if (d->pix.isError()) {
+ d->status = Error;
+ qmlInfo(this) << d->pix.error();
} else {
- d->pendingPixmapCache = false;
- QString errorString;
- if (QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async) != QDeclarativePixmapReply::Ready) {
- d->status = Error;
- qmlInfo(this) << errorString;
- }
+ d->status = Ready;
}
+
setImplicitWidth(impsize.width());
setImplicitHeight(impsize.height());
- if (d->status == Loading)
- d->status = Ready;
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(1.0);
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
index 01e4a00..65583d6 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
@@ -66,7 +66,6 @@ class QDeclarativeBorderImagePrivate : public QDeclarativeImageBasePrivate
public:
QDeclarativeBorderImagePrivate()
: border(0), sciReply(0),
- sciPendingPixmapCache(false),
horizontalTileMode(QDeclarativeBorderImage::Stretch),
verticalTileMode(QDeclarativeBorderImage::Stretch),
redirectCount(0)
@@ -97,7 +96,6 @@ public:
QDeclarativeScaleGrid *border;
QUrl sciurl;
QNetworkReply *sciReply;
- bool sciPendingPixmapCache;
QDeclarativeBorderImage::TileMode horizontalTileMode;
QDeclarativeBorderImage::TileMode verticalTileMode;
int redirectCount;
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index a40546f..70cbf74 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -641,18 +641,6 @@ void QDeclarativeFlickable::setFlickableDirection(FlickableDirection direction)
}
}
-QDeclarativeFlickable::FlickableDirection QDeclarativeFlickable::flickDirection() const
-{
- qmlInfo(this) << "'flickDirection' is deprecated. Please use 'flickableDirection' instead.";
- return flickableDirection();
-}
-
-void QDeclarativeFlickable::setFlickDirection(FlickableDirection direction)
-{
- qmlInfo(this) << "'flickDirection' is deprecated. Please use 'flickableDirection' instead.";
- setFlickableDirection(direction);
-}
-
void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10))
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
index 47746c6..44f2bcf 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
@@ -74,7 +74,6 @@ class Q_AUTOTEST_EXPORT QDeclarativeFlickable : public QDeclarativeItem
Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
Q_PROPERTY(bool flickingHorizontally READ isFlickingHorizontally NOTIFY flickingHorizontallyChanged)
Q_PROPERTY(bool flickingVertically READ isFlickingVertically NOTIFY flickingVerticallyChanged)
- Q_PROPERTY(FlickableDirection flickDirection READ flickDirection WRITE setFlickDirection NOTIFY flickableDirectionChanged) // deprecated
Q_PROPERTY(FlickableDirection flickableDirection READ flickableDirection WRITE setFlickableDirection NOTIFY flickableDirectionChanged)
Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged)
@@ -147,8 +146,6 @@ public:
QDeclarativeItem *contentItem();
enum FlickableDirection { AutoFlickDirection=0x00, HorizontalFlick=0x01, VerticalFlick=0x02, HorizontalAndVerticalFlick=0x03 };
- FlickableDirection flickDirection() const; // deprecated
- void setFlickDirection(FlickableDirection); // deprecated
FlickableDirection flickableDirection() const;
void setFlickableDirection(FlickableDirection);
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index cb99129..3efb9ad 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -1216,6 +1216,11 @@ void QDeclarativeGridView::setModel(const QVariant &model)
} else {
d->moveReason = QDeclarativeGridViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
+ if (d->highlight && d->currentItem) {
+ d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
+ d->updateTrackedItem();
+ }
+ d->moveReason = QDeclarativeGridViewPrivate::Other;
}
}
connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
@@ -1274,6 +1279,11 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate)
refill();
d->moveReason = QDeclarativeGridViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
+ if (d->highlight && d->currentItem) {
+ d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
+ d->updateTrackedItem();
+ }
+ d->moveReason = QDeclarativeGridViewPrivate::Other;
}
emit delegateChanged();
}
@@ -1300,7 +1310,6 @@ void QDeclarativeGridView::setCurrentIndex(int index)
return;
if (isComponentComplete() && d->isValid() && index != d->currentIndex && index < d->model->count() && index >= 0) {
d->moveReason = QDeclarativeGridViewPrivate::SetIndex;
- cancelFlick();
d->updateCurrent(index);
} else if (index != d->currentIndex) {
d->currentIndex = index;
@@ -2158,7 +2167,7 @@ void QDeclarativeGridView::componentComplete()
d->updateCurrent(0);
else
d->updateCurrent(d->currentIndex);
- if (d->highlight) {
+ if (d->highlight && d->currentItem) {
d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
d->updateTrackedItem();
}
@@ -2172,20 +2181,17 @@ void QDeclarativeGridView::trackedPositionChanged()
Q_D(QDeclarativeGridView);
if (!d->trackedItem || !d->currentItem)
return;
- if (!d->flickingHorizontally && !d->flickingVertically && !d->movingHorizontally && !d->movingVertically
- && d->moveReason == QDeclarativeGridViewPrivate::SetIndex) {
+ if (d->moveReason == QDeclarativeGridViewPrivate::SetIndex) {
const qreal trackedPos = d->trackedItem->rowPos();
const qreal viewPos = d->position();
+ qreal pos = viewPos;
if (d->haveHighlightRange) {
if (d->highlightRange == StrictlyEnforceRange) {
- qreal pos = viewPos;
if (trackedPos > pos + d->highlightRangeEnd - d->rowSize())
pos = trackedPos - d->highlightRangeEnd + d->rowSize();
if (trackedPos < pos + d->highlightRangeStart)
pos = trackedPos - d->highlightRangeStart;
- d->setPosition(pos);
} else {
- qreal pos = viewPos;
if (trackedPos < d->startPosition() + d->highlightRangeStart) {
pos = d->startPosition();
} else if (d->trackedItem->endRowPos() > d->endPosition() - d->size() + d->highlightRangeEnd) {
@@ -2199,14 +2205,12 @@ void QDeclarativeGridView::trackedPositionChanged()
pos = trackedPos - d->highlightRangeEnd + d->rowSize();
}
}
- d->setPosition(pos);
}
} else {
if (trackedPos < viewPos && d->currentItem->rowPos() < viewPos) {
- d->setPosition(d->currentItem->rowPos() < trackedPos ? trackedPos : d->currentItem->rowPos());
+ pos = d->currentItem->rowPos() < trackedPos ? trackedPos : d->currentItem->rowPos();
} else if (d->trackedItem->endRowPos() > viewPos + d->size()
&& d->currentItem->endRowPos() > viewPos + d->size()) {
- qreal pos;
if (d->trackedItem->endRowPos() < d->currentItem->endRowPos()) {
pos = d->trackedItem->endRowPos() - d->size();
if (d->rowSize() > d->size())
@@ -2216,9 +2220,12 @@ void QDeclarativeGridView::trackedPositionChanged()
if (d->rowSize() > d->size())
pos = d->currentItem->rowPos();
}
- d->setPosition(pos);
}
}
+ if (viewPos != pos) {
+ cancelFlick();
+ d->setPosition(pos);
+ }
}
}
@@ -2563,6 +2570,12 @@ void QDeclarativeGridView::modelReset()
refill();
d->moveReason = QDeclarativeGridViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
+ if (d->highlight && d->currentItem) {
+ d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
+ d->updateTrackedItem();
+ }
+ d->moveReason = QDeclarativeGridViewPrivate::Other;
+
emit countChanged();
}
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp
index ff61302..e0db580 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -126,7 +126,7 @@ QDeclarativeImage::~QDeclarativeImage()
QPixmap QDeclarativeImage::pixmap() const
{
Q_D(const QDeclarativeImage);
- return d->pix;
+ return d->pix.pixmap();
}
void QDeclarativeImage::setPixmap(const QPixmap &pix)
@@ -140,7 +140,7 @@ void QDeclarativeImage::setPixmap(const QPixmap &pix)
void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap)
{
Q_Q(QDeclarativeImage);
- pix = pixmap;
+ pix.setPixmap(pixmap);
q->setImplicitWidth(pix.width());
q->setImplicitHeight(pix.height());
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
index c3f8195..67f2327 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
@@ -57,9 +57,6 @@ QDeclarativeImageBase::QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, Q
QDeclarativeImageBase::~QDeclarativeImageBase()
{
- Q_D(QDeclarativeImageBase);
- if (d->pendingPixmapCache)
- QDeclarativePixmapCache::cancel(d->url, this);
}
QDeclarativeImageBase::Status QDeclarativeImageBase::status() const
@@ -91,7 +88,6 @@ void QDeclarativeImageBase::setAsynchronous(bool async)
}
}
-
QUrl QDeclarativeImageBase::source() const
{
Q_D(const QDeclarativeImageBase);
@@ -105,11 +101,6 @@ void QDeclarativeImageBase::setSource(const QUrl &url)
if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
return;
- if (d->pendingPixmapCache) {
- QDeclarativePixmapCache::cancel(d->url, this);
- d->pendingPixmapCache = false;
- }
-
d->url = url;
emit sourceChanged(d->url);
@@ -122,6 +113,7 @@ void QDeclarativeImageBase::setSourceSize(const QSize& size)
Q_D(QDeclarativeImageBase);
if (d->sourcesize == size)
return;
+
d->sourcesize = size;
emit sourceSizeChanged();
if (isComponentComplete())
@@ -143,7 +135,7 @@ void QDeclarativeImageBase::load()
}
if (d->url.isEmpty()) {
- d->pix = QPixmap();
+ d->pix.clear();
d->status = Null;
setImplicitWidth(0);
setImplicitHeight(0);
@@ -152,48 +144,37 @@ void QDeclarativeImageBase::load()
update();
} else {
d->status = Loading;
- int reqwidth = d->sourcesize.width();
- int reqheight = d->sourcesize.height();
- QSize impsize;
- QString errorString;
- QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async, reqwidth, reqheight);
- if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) {
- QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url, reqwidth, reqheight);
- d->pendingPixmapCache = true;
-
- static int replyDownloadProgress = -1;
- static int replyFinished = -1;
+
+ d->pix.load(qmlEngine(this), d->url, d->sourcesize, d->async);
+
+ if (d->pix.isLoading()) {
+
static int thisRequestProgress = -1;
static int thisRequestFinished = -1;
- if (replyDownloadProgress == -1) {
- replyDownloadProgress =
- QDeclarativePixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
- replyFinished =
- QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()");
+ if (thisRequestProgress == -1) {
thisRequestProgress =
QDeclarativeImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
thisRequestFinished =
QDeclarativeImageBase::staticMetaObject.indexOfSlot("requestFinished()");
}
- QMetaObject::connect(reply, replyFinished, this,
- thisRequestFinished, Qt::DirectConnection);
- QMetaObject::connect(reply, replyDownloadProgress, this,
- thisRequestProgress, Qt::DirectConnection);
+ d->pix.connectFinished(this, thisRequestFinished);
+ d->pix.connectDownloadProgress(this, thisRequestProgress);
+
} else {
- //### should be unified with requestFinished
- if (status == QDeclarativePixmapReply::Ready) {
- setImplicitWidth(impsize.width());
- setImplicitHeight(impsize.height());
+ QSize impsize = d->pix.implicitSize();
+ setImplicitWidth(impsize.width());
+ setImplicitHeight(impsize.height());
- if (d->status == Loading)
- d->status = Ready;
+ if (d->pix.isReady()) {
+ d->status = Ready;
if (!d->sourcesize.isValid())
emit sourceSizeChanged();
+
} else {
d->status = Error;
- qmlInfo(this) << errorString;
+ qmlInfo(this) << d->pix.error();
}
d->progress = 1.0;
emit statusChanged(d->status);
@@ -201,6 +182,7 @@ void QDeclarativeImageBase::load()
pixmapChange();
update();
}
+
}
emit statusChanged(d->status);
@@ -210,14 +192,13 @@ void QDeclarativeImageBase::requestFinished()
{
Q_D(QDeclarativeImageBase);
- d->pendingPixmapCache = false;
+ QSize impsize = d->pix.implicitSize();
- QSize impsize;
- QString errorString;
- if (QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async, d->sourcesize.width(), d->sourcesize.height()) != QDeclarativePixmapReply::Ready) {
+ if (d->pix.isError()) {
d->status = Error;
- qmlInfo(this) << errorString;
+ qmlInfo(this) << d->pix.error();
}
+
setImplicitWidth(impsize.width());
setImplicitHeight(impsize.height());
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
index 392c1db..aee8b28 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
@@ -54,6 +54,7 @@
//
#include "private/qdeclarativeitem_p.h"
+#include "private/qdeclarativepixmapcache_p.h"
#include <QtCore/QPointer>
@@ -68,18 +69,16 @@ public:
QDeclarativeImageBasePrivate()
: status(QDeclarativeImageBase::Null),
progress(0.0),
- pendingPixmapCache(false),
async(false)
{
QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
- QPixmap pix;
+ QDeclarativePixmap pix;
QDeclarativeImageBase::Status status;
QUrl url;
qreal progress;
QSize sourcesize;
- bool pendingPixmapCache : 1;
bool async : 1;
};
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 4abffc6..bd935c9 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -2145,7 +2145,7 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
\property QDeclarativeItem::baselineOffset
\brief The position of the item's baseline in local coordinates.
- The baseline of a Text item is the imaginary line on which the text
+ The baseline of a \l Text item is the imaginary line on which the text
sits. Controls containing text usually set their baseline to the
baseline of their text.
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index e519bd9..9497cb7 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -1547,6 +1547,10 @@ void QDeclarativeListView::setModel(const QVariant &model)
} else {
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
+ if (d->highlight && d->currentItem) {
+ d->highlight->setPosition(d->currentItem->position());
+ d->updateTrackedItem();
+ }
}
}
connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
@@ -1610,6 +1614,10 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate)
refill();
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
+ if (d->highlight && d->currentItem) {
+ d->highlight->setPosition(d->currentItem->position());
+ d->updateTrackedItem();
+ }
}
}
emit delegateChanged();
@@ -1636,7 +1644,6 @@ void QDeclarativeListView::setCurrentIndex(int index)
return;
if (isComponentComplete() && d->isValid() && index != d->currentIndex && index < d->model->count() && index >= 0) {
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
- cancelFlick();
d->updateCurrent(index);
} else if (index != d->currentIndex) {
d->currentIndex = index;
@@ -2439,7 +2446,6 @@ void QDeclarativeListView::incrementCurrentIndex()
if (currentIndex() < d->model->count() - 1 || d->wrap) {
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
int index = currentIndex()+1;
- cancelFlick();
d->updateCurrent(index < d->model->count() ? index : 0);
}
}
@@ -2458,7 +2464,6 @@ void QDeclarativeListView::decrementCurrentIndex()
if (currentIndex() > 0 || d->wrap) {
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
int index = currentIndex()-1;
- cancelFlick();
d->updateCurrent(index >= 0 ? index : d->model->count()-1);
}
}
@@ -2591,7 +2596,7 @@ void QDeclarativeListView::componentComplete()
d->updateCurrent(0);
else
d->updateCurrent(d->currentIndex);
- if (d->highlight) {
+ if (d->highlight && d->currentItem) {
d->highlight->setPosition(d->currentItem->position());
d->updateTrackedItem();
}
@@ -2611,20 +2616,17 @@ void QDeclarativeListView::trackedPositionChanged()
Q_D(QDeclarativeListView);
if (!d->trackedItem || !d->currentItem)
return;
- if (!d->flickingHorizontally && !d->flickingVertically && !d->movingHorizontally && !d->movingVertically
- && d->moveReason == QDeclarativeListViewPrivate::SetIndex) {
+ if (d->moveReason == QDeclarativeListViewPrivate::SetIndex) {
const qreal trackedPos = qCeil(d->trackedItem->position());
const qreal viewPos = d->position();
+ qreal pos = viewPos;
if (d->haveHighlightRange) {
if (d->highlightRange == StrictlyEnforceRange) {
- qreal pos = viewPos;
if (trackedPos > pos + d->highlightRangeEnd - d->trackedItem->size())
pos = trackedPos - d->highlightRangeEnd + d->trackedItem->size();
if (trackedPos < pos + d->highlightRangeStart)
pos = trackedPos - d->highlightRangeStart;
- d->setPosition(pos);
} else {
- qreal pos = viewPos;
if (trackedPos < d->startPosition() + d->highlightRangeStart) {
pos = d->startPosition();
} else if (d->trackedItem->endPosition() > d->endPosition() - d->size() + d->highlightRangeEnd) {
@@ -2638,14 +2640,12 @@ void QDeclarativeListView::trackedPositionChanged()
pos = trackedPos - d->highlightRangeEnd + d->trackedItem->size();
}
}
- d->setPosition(pos);
}
} else {
if (trackedPos < viewPos && d->currentItem->position() < viewPos) {
- d->setPosition(d->currentItem->position() < trackedPos ? trackedPos : d->currentItem->position());
+ pos = d->currentItem->position() < trackedPos ? trackedPos : d->currentItem->position();
} else if (d->trackedItem->endPosition() > viewPos + d->size()
&& d->currentItem->endPosition() > viewPos + d->size()) {
- qreal pos;
if (d->trackedItem->endPosition() < d->currentItem->endPosition()) {
pos = d->trackedItem->endPosition() - d->size();
if (d->trackedItem->size() > d->size())
@@ -2655,9 +2655,12 @@ void QDeclarativeListView::trackedPositionChanged()
if (d->currentItem->size() > d->size())
pos = d->currentItem->position();
}
- d->setPosition(pos);
}
}
+ if (viewPos != pos) {
+ cancelFlick();
+ d->setPosition(pos);
+ }
}
}
@@ -3021,6 +3024,11 @@ void QDeclarativeListView::modelReset()
refill();
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
d->updateCurrent(d->currentIndex);
+ if (d->highlight && d->currentItem) {
+ d->highlight->setPosition(d->currentItem->position());
+ d->updateTrackedItem();
+ }
+ d->moveReason = QDeclarativeListViewPrivate::Other;
emit countChanged();
}
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index c8c9e44..e745ca6 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -119,7 +119,7 @@ void QDeclarativeLoaderPrivate::initResize()
property, or loaded from a URL via the \l source property.
Loader can be used to delay the creation of a component until it is required.
- For example, this loads "Page1.qml" as a component into the \l Loader element
+ For example, this loads "Page1.qml" as a component into the Loader element
when the \l MouseArea is clicked:
\code
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
index 87da904..3be4014 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
@@ -85,6 +85,19 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
The \l model of a Repeater can be any of the supported \l {qmlmodels}{Data Models}.
+ Items instantiated by the Repeater are inserted, in order, as
+ children of the Repeater's parent. The insertion starts immediately after
+ the repeater's position in its parent stacking list. This allows
+ a Repeater to be used inside a layout. For example, the following Repeater's
+ items are stacked between a red rectangle and a blue rectangle:
+
+ \snippet doc/src/snippets/declarative/repeater.qml layout
+
+ \image repeater.png
+
+
+ \section2 The \c index and \c modelData properties
+
The index of a delegate is exposed as an accessible \c index property in the delegate.
Properties of the model are also available depending upon the type of \l {qmlmodels}{Data Model}.
@@ -105,25 +118,22 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\o \image repeater-modeldata.png
\endtable
- Items instantiated by the Repeater are inserted, in order, as
- children of the Repeater's parent. The insertion starts immediately after
- the repeater's position in its parent stacking list. This allows
- a Repeater to be used inside a layout. For example, the following Repeater's
- items are stacked between a red rectangle and a blue rectangle:
-
- \snippet doc/src/snippets/declarative/repeater.qml layout
-
- \image repeater.png
A Repeater item owns all items it instantiates. Removing or dynamically destroying
an item created by a Repeater results in unpredictable behavior.
- Note that if a repeater is
- required to instantiate a large number of items, it may be more efficient to
- use other view elements such as ListView.
- \note Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects.
- For example, it cannot be used to repeat QtObjects.
+ \section2 Considerations when using Repeater
+
+ The Repeater element creates all of its delegate items when the repeater is first
+ created. This can be inefficient if there are a large number of delegate items and
+ not all of the items are required to be visible at the same time. If this is the case,
+ consider using other view elements like ListView (which only creates delegate items
+ when they are scrolled into view) or use the \l {Dynamic Object Creation} methods to
+ create items as they are required.
+
+ Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects.
+ For example, it cannot be used to repeat QtObjects:
\badcode
Item {
//XXX does not work! Can't repeat QtObject as it doesn't derive from Item.
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 0bd9a53..200a680 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -61,52 +61,100 @@ class QTextDocumentWithImageResources : public QTextDocument {
Q_OBJECT
public:
- QTextDocumentWithImageResources(QDeclarativeText *parent) :
- QTextDocument(parent),
- outstanding(0)
- {
- }
+ QTextDocumentWithImageResources(QDeclarativeText *parent);
+ virtual ~QTextDocumentWithImageResources();
+ void setText(const QString &);
int resourcesLoading() const { return outstanding; }
protected:
- QVariant loadResource(int type, const QUrl &name)
- {
- QUrl url = qmlContext(parent())->resolvedUrl(name);
-
- if (type == QTextDocument::ImageResource) {
- QPixmap pm;
- QString errorString;
- QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(url, &pm, &errorString, 0, false, 0, 0);
- if (status == QDeclarativePixmapReply::Ready)
- return pm;
- if (status == QDeclarativePixmapReply::Error) {
- if (!errors.contains(url)) {
- errors.insert(url);
- qmlInfo(parent()) << errorString;
- }
- } else {
- QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(parent()), url);
- connect(reply, SIGNAL(finished()), this, SLOT(requestFinished()));
+ QVariant loadResource(int type, const QUrl &name);
+
+private slots:
+ void requestFinished();
+
+private:
+ QHash<QUrl, QDeclarativePixmap *> m_resources;
+
+ int outstanding;
+ static QSet<QUrl> errors;
+};
+
+QTextDocumentWithImageResources::QTextDocumentWithImageResources(QDeclarativeText *parent)
+: QTextDocument(parent), outstanding(0)
+{
+}
+
+QTextDocumentWithImageResources::~QTextDocumentWithImageResources()
+{
+ if (!m_resources.isEmpty())
+ qDeleteAll(m_resources);
+}
+
+QVariant QTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
+{
+ QDeclarativeContext *context = qmlContext(parent());
+ QUrl url = context->resolvedUrl(name);
+
+ if (type == QTextDocument::ImageResource) {
+ QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
+
+ if (iter == m_resources.end()) {
+ QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
+ iter = m_resources.insert(name, p);
+
+ if (p->isLoading()) {
+ p->connectFinished(this, SLOT(requestFinished()));
outstanding++;
}
}
- return QTextDocument::loadResource(type,url); // The *resolved* URL
+ QDeclarativePixmap *p = *iter;
+ if (p->isReady()) {
+ return p->pixmap();
+ } else if (p->isError()) {
+ if (!errors.contains(url)) {
+ errors.insert(url);
+ qmlInfo(parent()) << p->error();
+ }
+ }
}
-private slots:
- void requestFinished()
- {
- outstanding--;
- if (outstanding == 0)
- static_cast<QDeclarativeText*>(parent())->reloadWithResources();
+ return QTextDocument::loadResource(type,url); // The *resolved* URL
+}
+
+void QTextDocumentWithImageResources::requestFinished()
+{
+ outstanding--;
+ if (outstanding == 0) {
+ QDeclarativeText *textItem = static_cast<QDeclarativeText*>(parent());
+ QString text = textItem->text();
+#ifndef QT_NO_TEXTHTMLPARSER
+ setHtml(text);
+#else
+ setPlainText(text);
+#endif
+ QDeclarativeTextPrivate *d = QDeclarativeTextPrivate::get(textItem);
+ d->updateLayout();
+ d->markImgDirty();
}
+}
-private:
- int outstanding;
- static QSet<QUrl> errors;
-};
+void QTextDocumentWithImageResources::setText(const QString &text)
+{
+ if (!m_resources.isEmpty()) {
+ qWarning("CLEAR");
+ qDeleteAll(m_resources);
+ m_resources.clear();
+ outstanding = 0;
+ }
+
+#ifndef QT_NO_TEXTHTMLPARSER
+ setHtml(text);
+#else
+ setPlainText(text);
+#endif
+}
QSet<QUrl> QTextDocumentWithImageResources::errors;
@@ -314,11 +362,7 @@ void QDeclarativeText::setText(const QString &n)
if (d->richText) {
if (isComponentComplete()) {
d->ensureDoc();
-#ifndef QT_NO_TEXTHTMLPARSER
- d->doc->setHtml(n);
-#else
- d->doc->setPlainText(n);
-#endif
+ d->doc->setText(n);
}
}
@@ -607,11 +651,7 @@ void QDeclarativeText::setTextFormat(TextFormat format)
} else if (!wasRich && d->richText) {
if (isComponentComplete()) {
d->ensureDoc();
-#ifndef QT_NO_TEXTHTMLPARSER
- d->doc->setHtml(d->text);
-#else
- d->doc->setPlainText(d->text);
-#endif
+ d->doc->setText(d->text);
}
d->updateLayout();
d->markImgDirty();
@@ -671,6 +711,8 @@ QRectF QDeclarativeText::boundingRect() const
int x = 0;
int y = 0;
+ // Could include font max left/right bearings to either side of rectangle.
+
if (d->cache || d->style != Normal) {
switch (d->hAlign) {
case AlignLeft:
@@ -1074,20 +1116,6 @@ void QDeclarativeTextPrivate::ensureDoc()
}
}
-void QDeclarativeText::reloadWithResources()
-{
- Q_D(QDeclarativeText);
- if (!d->richText)
- return;
-#ifndef QT_NO_TEXTHTMLPARSER
- d->doc->setHtml(d->text);
-#else
- d->doc->setPlainText(d->text);
-#endif
- d->updateLayout();
- d->markImgDirty();
-}
-
/*!
Returns the number of resources (images) that are being loaded asynchronously.
*/
@@ -1173,11 +1201,7 @@ void QDeclarativeText::componentComplete()
if (d->dirty) {
if (d->richText) {
d->ensureDoc();
-#ifndef QT_NO_TEXTHTMLPARSER
- d->doc->setHtml(d->text);
-#else
- d->doc->setPlainText(d->text);
-#endif
+ d->doc->setText(d->text);
}
d->updateLayout();
d->dirty = false;
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p.h b/src/declarative/graphicsitems/qdeclarativetext_p.h
index cd97df3..2cc4d52 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p.h
@@ -168,9 +168,6 @@ protected:
private:
Q_DISABLE_COPY(QDeclarativeText)
Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeText)
-
- friend class QTextDocumentWithImageResources;
- void reloadWithResources();
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p_p.h b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
index 332f99e..51a5514 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
@@ -124,6 +124,10 @@ public:
QSize cachedLayoutSize;
QDeclarativeText::TextFormat format;
QDeclarativeText::WrapMode wrapMode;
+
+ static inline QDeclarativeTextPrivate *get(QDeclarativeText *t) {
+ return t->d_func();
+ }
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index c6566ff..f3eef23 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -203,7 +203,7 @@ QString QDeclarativeTextEdit::text() const
Sets the font size in pixels.
Using this function makes the font device dependent.
- Use \l pointSize to set the size of the font in a device independent manner.
+ Use \l font.pointSize to set the size of the font in a device independent manner.
*/
/*!
@@ -1263,6 +1263,15 @@ void QDeclarativeTextEditPrivate::init()
control = new QTextControl(q);
control->setIgnoreUnusedNavigationEvents(true);
+ // QTextControl follows the default text color
+ // defined by the platform, declarative text
+ // should be black by default
+ QPalette pal = control->palette();
+ if (pal.color(QPalette::Text) != color) {
+ pal.setColor(QPalette::Text, color);
+ control->setPalette(pal);
+ }
+
QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateImgCache(QRectF)));
QObject::connect(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
@@ -1332,6 +1341,15 @@ QRectF QDeclarativeTextEdit::boundingRect() const
{
Q_D(const QDeclarativeTextEdit);
QRectF r = QDeclarativePaintedItem::boundingRect();
+ int cursorWidth = 1;
+ if(d->cursor)
+ cursorWidth = d->cursor->width();
+ if(!d->document->isEmpty())
+ cursorWidth += 3;// ### Need a better way of accounting for space between char and cursor
+
+ // Could include font max left/right bearings to either side of rectangle.
+
+ r.setRight(r.right() + cursorWidth);
return r.translated(0,d->yoff);
}
@@ -1371,12 +1389,6 @@ void QDeclarativeTextEdit::updateSize()
int newWidth = qCeil(d->document->idealWidth());
if (!widthValid() && d->document->textWidth() != newWidth)
d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
- int cursorWidth = 1;
- if(d->cursor)
- cursorWidth = d->cursor->width();
- newWidth += cursorWidth;
- if(!d->document->isEmpty())
- newWidth += 3;// ### Need a better way of accounting for space between char and cursor
// ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
setImplicitWidth(newWidth);
qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index ed999a2..5325f25 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -100,8 +100,6 @@ void QDeclarativeTextInput::setText(const QString &s)
if(s == text())
return;
d->control->setText(s);
- d->updateHorizontalScroll();
- //emit textChanged();
}
/*!
@@ -550,9 +548,9 @@ void QDeclarativeTextInput::setAutoScroll(bool b)
return;
d->autoScroll = b;
- d->updateHorizontalScroll();
//We need to repaint so that the scrolling is taking into account.
updateSize(true);
+ d->updateHorizontalScroll();
emit autoScrollChanged(d->autoScroll);
}
@@ -826,7 +824,7 @@ void QDeclarativeTextInput::createCursor()
QDeclarative_setParent_noEvent(d->cursorItem, this);
d->cursorItem->setParentItem(this);
d->cursorItem->setX(d->control->cursorToX());
- d->cursorItem->setHeight(d->control->height());
+ d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
}
void QDeclarativeTextInput::moveCursor()
@@ -910,6 +908,7 @@ void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev)
void QDeclarativeTextInput::inputMethodEvent(QInputMethodEvent *ev)
{
Q_D(QDeclarativeTextInput);
+ ev->ignore();
inputMethodPreHandler(ev);
if (ev->isAccepted())
return;
@@ -1020,27 +1019,31 @@ bool QDeclarativeTextInput::event(QEvent* ev)
void QDeclarativeTextInput::geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry)
{
- if (newGeometry.width() != oldGeometry.width())
+ Q_D(QDeclarativeTextInput);
+ if (newGeometry.width() != oldGeometry.width()) {
updateSize();
+ d->updateHorizontalScroll();
+ }
QDeclarativePaintedItem::geometryChanged(newGeometry, oldGeometry);
}
+int QDeclarativeTextInputPrivate::calculateTextWidth()
+{
+ return qRound(control->naturalTextWidth());
+}
+
void QDeclarativeTextInputPrivate::updateHorizontalScroll()
{
Q_Q(QDeclarativeTextInput);
- QFontMetrics fm = QFontMetrics(font);
int cix = qRound(control->cursorToX());
QRect br(q->boundingRect().toRect());
- //###Is this using bearing appropriately?
- int minLB = qMax(0, -fm.minLeftBearing());
- int minRB = qMax(0, -fm.minRightBearing());
- int widthUsed = qRound(control->naturalTextWidth()) + 1 + minRB;
+ int widthUsed = calculateTextWidth();
if (autoScroll) {
- if ((minLB + widthUsed) <= br.width()) {
+ if (widthUsed <= br.width()) {
// text fits in br; use hscroll for alignment
switch (hAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
case Qt::AlignRight:
- hscroll = widthUsed - br.width() + 1;
+ hscroll = widthUsed - br.width() - 1;
break;
case Qt::AlignHCenter:
hscroll = (widthUsed - br.width()) / 2;
@@ -1050,7 +1053,6 @@ void QDeclarativeTextInputPrivate::updateHorizontalScroll()
hscroll = 0;
break;
}
- hscroll -= minLB;
} else if (cix - hscroll >= br.width()) {
// text doesn't fit, cursor is to the right of br (scroll right)
hscroll = cix - br.width() + 1;
@@ -1070,7 +1072,6 @@ void QDeclarativeTextInputPrivate::updateHorizontalScroll()
} else {
hscroll = 0;
}
- hscroll -= minLB;
}
}
@@ -1095,7 +1096,6 @@ void QDeclarativeTextInput::drawContents(QPainter *p, const QRect &r)
offset = QPoint(d->hscroll, 0);
}
d->control->draw(p, offset, r, flags);
-
p->restore();
}
@@ -1448,8 +1448,8 @@ void QDeclarativeTextInput::selectionChanged()
void QDeclarativeTextInput::q_textChanged()
{
Q_D(QDeclarativeTextInput);
- d->updateHorizontalScroll();
updateSize();
+ d->updateHorizontalScroll();
updateMicroFocus();
emit textChanged();
emit displayTextChanged();
@@ -1469,16 +1469,26 @@ void QDeclarativeTextInput::updateRect(const QRect &r)
update();
}
+QRectF QDeclarativeTextInput::boundingRect() const
+{
+ Q_D(const QDeclarativeTextInput);
+ QRectF r = QDeclarativePaintedItem::boundingRect();
+
+ int cursorWidth = d->cursorItem ? d->cursorItem->width() : d->control->cursorWidth();
+
+ // Could include font max left/right bearings to either side of rectangle.
+
+ r.setRight(r.right() + cursorWidth);
+ return r;
+}
+
void QDeclarativeTextInput::updateSize(bool needsRedraw)
{
Q_D(QDeclarativeTextInput);
int w = width();
int h = height();
- setImplicitHeight(d->control->height());
- int cursorWidth = d->control->cursorWidth();
- if(d->cursorItem)
- cursorWidth = d->cursorItem->width();
- setImplicitWidth(d->control->naturalTextWidth() + cursorWidth);
+ setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
+ setImplicitWidth(d->calculateTextWidth());
setContentsSize(QSize(width(), height()));//Repaints if changed
if(w==width() && h==height() && needsRedraw){
clearCache();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index bacd041..ded0d09 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -187,6 +187,8 @@ public:
void drawContents(QPainter *p,const QRect &r);
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ QRectF boundingRect() const;
+
Q_SIGNALS:
void textChanged();
void cursorPositionChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index 8b74bcc..4ac5134 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -100,6 +100,7 @@ public:
void startCreatingCursor();
void focusChanged(bool hasFocus);
void updateHorizontalScroll();
+ int calculateTextWidth();
QLineControl* control;
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 623e3df..e3ce70e 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -228,10 +228,10 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
}
break;
case QMetaType::Float:
- if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: float expected"));
+ if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: number expected"));
break;
case QVariant::Double:
- if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: double expected"));
+ if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: number expected"));
break;
case QVariant::Color:
{
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 9d3032c..8b013fe 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -68,14 +68,44 @@ class QByteArray;
/*!
\class QDeclarativeComponent
\since 4.7
- \brief The QDeclarativeComponent class encapsulates a QML component description.
+ \brief The QDeclarativeComponent class encapsulates a QML component definition.
\mainclass
+
+ Components are reusable, encapsulated QML elements with well-defined interfaces.
+ They are often defined in \l {qdeclarativedocuments.html}{Component Files}.
+
+ A QDeclarativeComponent instance can be created from a QML file.
+ For example, if there is a \c main.qml file like this:
+
+ \qml
+ import Qt 4.7
+
+ Item {
+ width: 200
+ height: 200
+ }
+ \endqml
+
+ The following code loads this QML file as a component, creates an instance of
+ this component using create(), and then queries the \l Item's \l {Item::}{width}
+ value:
+
+ \code
+ QDeclarativeEngine *engine = new QDeclarativeEngine;
+ QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml"));
+
+ QObject *myObject = component.create();
+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(myObject);
+ int width = item->width();
+ \endcode
+
+ \sa {Using QML in C++ Applications}
*/
/*!
\qmlclass Component QDeclarativeComponent
\since 4.7
- \brief The Component element encapsulates a QML component description.
+ \brief The Component element encapsulates a QML component definition.
Components are reusable, encapsulated QML elements with well-defined interfaces.
They are often defined in \l {qdeclarativedocuments.html}{Component Files}.
@@ -448,7 +478,8 @@ void QDeclarativeComponent::loadUrl(const QUrl &url)
d->clear();
- if (url.isRelative() && !url.isEmpty())
+ if ((url.isRelative() && !url.isEmpty())
+ || url.scheme() == QLatin1String("file")) // Workaround QTBUG-11929
d->url = d->engine->baseUrl().resolved(url);
else
d->url = url;
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 60e9dd3..3d25291 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -145,6 +145,8 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
has been created in that context is an expensive operation (essentially forcing all bindings
to reevaluate). Thus whenever possible you should complete "setup" of the context
before using it to create any objects.
+
+ \sa {Using QML in C++ Applications}
*/
/*! \internal */
diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp
index a3cddb5..5b30bde 100644
--- a/src/declarative/qml/qdeclarativedom.cpp
+++ b/src/declarative/qml/qdeclarativedom.cpp
@@ -493,7 +493,7 @@ int QDeclarativeDomDynamicProperty::propertyType() const
return QMetaType::type("int");
case QDeclarativeParser::Object::DynamicProperty::Real:
- return QMetaType::type("double");
+ return sizeof(qreal) == sizeof(double) ? QMetaType::type("double") : QMetaType::type("float");
case QDeclarativeParser::Object::DynamicProperty::String:
return QMetaType::type("QString");
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 8b15ae9..8bf7450 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -151,6 +151,7 @@ void QDeclarativeEnginePrivate::defineModule()
}
/*!
+\keyword QmlGlobalQtObject
\qmlclass Qt QDeclarativeEnginePrivate
\brief The QML global Qt object provides useful enums and functions from Qt.
@@ -1077,7 +1078,7 @@ If you are certain the files will be local, you could simplify to:
\snippet doc/src/snippets/declarative/componentCreation.js 2
To create a QML object from an arbitrary string of QML (instead of a file),
-use \l{Qt::createQmlObject()}{Qt.createQmlObject()}.
+use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
@@ -1124,7 +1125,7 @@ Each object in this array has the members \c lineNumber, \c columnNumber, \c fil
Note that this function returns immediately, and therefore may not work if
the \a qml string loads new components (that is, external QML files that have not yet been loaded).
-If this is the case, consider using \l{Qt::createComponent()}{Qt.createComponent()} instead.
+If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
*/
QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
@@ -1728,8 +1729,7 @@ void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const
/*!
\qmlmethod Qt::quit()
This function causes the QDeclarativeEngine::quit() signal to be emitted.
-Within the \l {Qt Declarative UI Runtime}{qml} application this causes the
-launcher application to exit.
+Within the \l {QML Viewer}, this causes the launcher application to exit.
*/
QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 8ae5f2f..96cdec1 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -214,8 +214,30 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex
/*!
\class QDeclarativeExpression
- \since 4.7
+ \since 4.7
\brief The QDeclarativeExpression class evaluates JavaScript in a QML context.
+
+ For example, given a file \c main.qml like this:
+
+ \qml
+ import Qt 4.7
+
+ Item {
+ width: 200; height: 200
+ }
+ \endqml
+
+ The following code evaluates a JavaScript expression in the context of the
+ above QML:
+
+ \code
+ QDeclarativeEngine *engine = new QDeclarativeEngine;
+ QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml"));
+
+ QObject *myObject = component.create();
+ QDeclarativeExpression *expr = new QDeclarativeExpression(engine->rootContext(), myObject, "width * 2");
+ int result = expr->evaluate().toInt(); // result = 400
+ \endcode
*/
/*!
diff --git a/src/declarative/qml/qdeclarativeextensionplugin.cpp b/src/declarative/qml/qdeclarativeextensionplugin.cpp
index c2e8300..0660599 100644
--- a/src/declarative/qml/qdeclarativeextensionplugin.cpp
+++ b/src/declarative/qml/qdeclarativeextensionplugin.cpp
@@ -67,10 +67,8 @@ QT_BEGIN_NAMESPACE
See \l {Tutorial: Writing QML extensions with C++} for details on creating
QML extensions, including how to build a plugin with with QDeclarativeExtensionPlugin.
For a simple overview, see the \l{declarative/cppextensions/plugins}{plugins} example.
-
- Also see \l {How to Create Qt Plugins} for general Qt plugin documentation.
- \sa QDeclarativeEngine::importPlugin()
+ \sa QDeclarativeEngine::importPlugin(), {How to Create Qt Plugins}
*/
/*!
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index a2e3831..8d81b34 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -409,7 +409,8 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl);
if (!localFileOrQrc.isEmpty()) {
QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
- if (dir.isEmpty() || !QDir().exists(dir)) {
+ QFileInfo dirinfo(dir);
+ if (dir.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
if (errorString)
*errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg);
return false; // local import dirs must exist
@@ -425,7 +426,8 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
if (prefix.isEmpty()) {
// directory must at least exist for valid import
QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
- if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) {
+ QFileInfo dirinfo(localFileOrQrc);
+ if (localFileOrQrc.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
if (errorString) {
if (localFileOrQrc.isEmpty())
*errorString = QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri);
@@ -445,11 +447,23 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
if (vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin();
+ int lowest_maj = INT_MAX;
+ int lowest_min = INT_MAX;
+ int highest_maj = INT_MIN;
+ int highest_min = INT_MIN;
for (; it != qmldircomponents.end(); ++it) {
- if (it->majorVersion > vmaj || (it->majorVersion == vmaj && it->minorVersion >= vmin))
- break;
+ if (it->majorVersion > highest_maj || (it->majorVersion == highest_maj && it->minorVersion > highest_min)) {
+ highest_maj = it->majorVersion;
+ highest_min = it->minorVersion;
+ }
+ if (it->majorVersion < lowest_maj || (it->majorVersion == lowest_maj && it->minorVersion < lowest_min)) {
+ lowest_maj = it->majorVersion;
+ lowest_min = it->minorVersion;
+ }
}
- if (it == qmldircomponents.end()) {
+ if (lowest_maj > vmaj || (lowest_maj == vmaj && lowest_min > vmin)
+ || highest_maj < vmaj || (highest_maj == vmaj && highest_min < vmin))
+ {
*errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
return false;
}
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index c32cab6..153e2be 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -1152,7 +1152,7 @@ bool QDeclarativeMetaType::copy(int type, void *data, const void *copy)
*static_cast<float *>(data) = float(0);
return true;
case QMetaType::Double:
- *static_cast<double *>(data) = double();
+ *static_cast<double *>(data) = double(0);
return true;
case QMetaType::QChar:
*static_cast<NS(QChar) *>(data) = NS(QChar)();
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..fdc2455 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;
- static QHash<QDeclarativeEngine *,QDeclarativeImageReader*> readers;
+ QHash<QNetworkReply*,QDeclarativePixmapReply*> replies;
+
+ 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;
-static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int req_width, int req_height)
+int QDeclarativePixmapReader::replyDownloadProgress = -1;
+int QDeclarativePixmapReader::replyFinished = -1;
+int QDeclarativePixmapReader::downloadProgress = -1;
+int QDeclarativePixmapReader::thisNetworkRequestDone = -1;
+
+
+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;
- }
-
- 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);
+ eventLoopQuitHack = new QObject;
+ eventLoopQuitHack->moveToThread(this);
+ connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
+ start(QThread::IdlePriority);
+}
- 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,141 @@ 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));
+ job->postReply(error, errorString, readSize, image);
}
- // kick off event loop again if we have dropped below max request count
- if (replies.count() == maxImageRequestCount)
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
reply->deleteLater();
+
+ // kick off event loop again incase we have dropped below max request count
+ threadObject->processJobs();
}
-//===========================================================================
+QDeclarativePixmapReader::ThreadObject::ThreadObject(QDeclarativePixmapReader *i)
+: reader(i)
+{
+}
+
+void QDeclarativePixmapReader::ThreadObject::processJobs()
+{
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+}
-QDeclarativeImageReader::QDeclarativeImageReader(QDeclarativeEngine *eng)
- : QThread(eng), engine(eng), handler(0)
+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();
+ }
+ }
+}
+
+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());
+ }
+
+ runningJob->postReply(errorCode, errorStr, readSize, image);
+ } 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;
+ }
+ runningJob->postReply(errorCode, errorStr, readSize, 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);
+ }
+ }
}
-QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *engine)
+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 +483,510 @@ 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);
+int QDeclarativePixmapData::cost() const
+{
+ return pixmap.width() * pixmap.height() * pixmap.depth();
}
-QString QDeclarativePixmapReply::errorString() const
+void QDeclarativePixmapData::addref()
{
- Q_D(const QDeclarativePixmapReply);
- return d->errorString;
+ ++refCount;
+ if (prevUnreferencedPtr)
+ pixmapStore()->referencePixmap(this);
}
-QDeclarativePixmapReply::Status QDeclarativePixmapReply::status() const
+void QDeclarativePixmapData::release()
{
- Q_D(const QDeclarativePixmapReply);
- return d->status;
+ 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;
+ }
+ }
}
-bool QDeclarativePixmapReply::isLoading() const
+void QDeclarativePixmapData::addToCache()
{
- Q_D(const QDeclarativePixmapReply);
- return d->loading;
+ if (!inCache) {
+ QDeclarativePixmapKey key = { &url, &requestSize };
+ pixmapStore()->m_cache.insert(key, this);
+ inCache = true;
+ }
}
-void QDeclarativePixmapReply::setLoading()
+void QDeclarativePixmapData::removeFromCache()
{
- Q_D(QDeclarativePixmapReply);
- d->loading = true;
+ if (inCache) {
+ QDeclarativePixmapKey key = { &url, &requestSize };
+ pixmapStore()->m_cache.remove(key);
+ inCache = false;
+ }
}
-void QDeclarativePixmapReply::addRef()
+struct QDeclarativePixmapNull {
+ QUrl url;
+ QPixmap pixmap;
+ QSize size;
+};
+Q_GLOBAL_STATIC(QDeclarativePixmapNull, nullPixmap);
+
+QDeclarativePixmap::QDeclarativePixmap()
+: d(0)
{
- Q_D(QDeclarativePixmapReply);
- ++d->refCount;
}
-bool QDeclarativePixmapReply::release(bool defer)
+QDeclarativePixmap::QDeclarativePixmap(QDeclarativeEngine *engine, const QUrl &url)
+: d(0)
{
- 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);
+ load(engine, url);
+}
+
+QDeclarativePixmap::QDeclarativePixmap(QDeclarativeEngine *engine, const QUrl &url, const QSize &size)
+: d(0)
+{
+ load(engine, url, size);
+}
+
+QDeclarativePixmap::~QDeclarativePixmap()
+{
+ if (d) {
+ d->release();
+ d = 0;
}
+}
- return false;
+bool QDeclarativePixmap::isNull() const
+{
+ return d == 0;
}
-/*!
- 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.
+bool QDeclarativePixmap::isReady() const
+{
+ return status() == Ready;
+}
- Returns Ready, or Error if the image has been retrieved,
- otherwise the current retrieval status.
+bool QDeclarativePixmap::isError() const
+{
+ return status() == Error;
+}
- 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.
+bool QDeclarativePixmap::isLoading() const
+{
+ return status() == Loading;
+}
- 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.
+QString QDeclarativePixmap::error() const
+{
+ if (d)
+ return d->errorString;
+ else
+ return QString();
+}
- 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::Status QDeclarativePixmap::status() const
{
- QDeclarativePixmapReply::Status status = QDeclarativePixmapReply::Unrequested;
- QByteArray key = url.toEncoded(QUrl::FormattingOption(0x100));
+ if (d)
+ return d->pixmapStatus;
+ else
+ return Null;
+}
- if (req_width > 0 || req_height > 0) {
- key += ':';
- key += QByteArray::number(req_width);
- key += 'x';
- key += QByteArray::number(req_height);
- }
+const QUrl &QDeclarativePixmap::url() const
+{
+ if (d)
+ return d->url;
+ else
+ return nullPixmap()->url;
+}
- QString strKey = QString::fromLatin1(key.constData(), key.count());
+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) {
+ QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
+ if (!localFile.isEmpty()) {
+ QFile f(localFile);
+ QSize readSize;
+ QString errorString;
-#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;
- }
+ if (readImage(url, &f, &image, &errorString, &readSize, requestSize)) {
+ d = new QDeclarativePixmapData(url, QPixmap::fromImage(image), readSize, requestSize);
+ d->addToCache();
+ return;
+ }
} 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;
+ errorString = tr("Cannot open: %1").arg(url.toString());
}
+
+ d = new QDeclarativePixmapData(url, requestSize, errorString);
+ return;
}
- 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;
- }
+ }
+
+ if (!engine)
+ return;
+
+ QDeclarativePixmapReader *reader = QDeclarativePixmapReader::instance(engine);
+
+ d = new QDeclarativePixmapData(url, requestSize);
+ d->addToCache();
- return status;
+ 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/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/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 0692aaa..00169db 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -589,7 +589,7 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
with a combined value of all key roles that is not already present in
the model.
- \sa {declarative/rssnews}{RSS News demo}
+ \sa {demos/declarative/rssnews}{RSS News demo}
*/
QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent)
@@ -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
{