summaryrefslogtreecommitdiffstats
path: root/src/declarative/graphicsitems
diff options
context:
space:
mode:
authorDavid Boddie <dboddie@trolltech.com>2010-07-16 15:46:21 (GMT)
committerDavid Boddie <dboddie@trolltech.com>2010-07-16 15:46:21 (GMT)
commit6b1b666574d6e27efdd3b243de8815a5278c3666 (patch)
tree7a5ac02fe569b3fc497ca8d0a333d10587eb3567 /src/declarative/graphicsitems
parenteef1d13743baddf41bd135d98fc2ad12944b8477 (diff)
parentab4dde176cfa314522964e5e5fbf9f2d388f8fdf (diff)
downloadQt-6b1b666574d6e27efdd3b243de8815a5278c3666.zip
Qt-6b1b666574d6e27efdd3b243de8815a5278c3666.tar.gz
Qt-6b1b666574d6e27efdd3b243de8815a5278c3666.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7
Conflicts: tools/qdoc3/test/qt.qdocconf
Diffstat (limited to 'src/declarative/graphicsitems')
-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.cpp14
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp42
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp99
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage_p.h2
-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.cpp43
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h20
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp50
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp14
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp38
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp174
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp24
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp92
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h1
22 files changed, 444 insertions, 365 deletions
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..9af5f56 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))
@@ -1354,7 +1342,7 @@ bool QDeclarativeFlickable::isFlickingVertically() const
This property holds the time to delay (ms) delivering a press to
children of the Flickable. This can be useful where reacting
- to a press before a flicking action has undesireable effects.
+ to a press before a flicking action has undesirable effects.
If the flickable is dragged/flicked before the delay times out
the press event will not be delivered. If the button is released
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..14a4f08 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;
@@ -1381,7 +1390,7 @@ void QDeclarativeGridView::setHighlight(QDeclarativeComponent *highlight)
highlight is not moved by the view, and any movement must be implemented
by the highlight.
- Here is a highlight with its motion defined by a \l {SpringFollow} item:
+ Here is a highlight with its motion defined by a \l {SpringAnimation} item:
\snippet doc/src/snippets/declarative/gridview/gridview.qml highlightFollowsCurrentItem
*/
@@ -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);
+ }
}
}
@@ -2431,8 +2438,11 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
if (removedVisible && d->visibleItems.isEmpty()) {
d->timeline.clear();
d->setPosition(0);
- if (d->itemCount == 0)
+ if (d->itemCount == 0) {
+ d->updateHeader();
+ d->updateFooter();
update();
+ }
}
emit countChanged();
@@ -2563,6 +2573,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..90738c8 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -65,18 +65,20 @@ QT_BEGIN_NAMESPACE
Image { source: "qtlogo.png" }
\endqml
\endtable
-
- If a size is not specified explicitly, the Image element is sized to the loaded image.
- Image elements can be stretched and tiled using the \l fillMode property.
- If the image \l source is a network resource, the image is loaded asynchronous and the
- \l progress and \l status properties are updated appropriately. Otherwise, if the image is
- available locally, it is loaded immediately and the user interface is blocked until loading is
- complete. (This is typically the correct behavior for user interface elements.)
- For large local images, which do not need to be visible immediately, it may be preferable to
- enable \l asynchronous loading. This loads the image in the background using a low priority thread.
+ If the \l {Image::width}{width} and \l{Image::height}{height} properties are not specified,
+ the Image element is automatically sized to the loaded image. Image elements can be
+ stretched and tiled using the \l fillMode property.
+
+ By default, locally available images are loaded immediately, and the user interface
+ is blocked until loading is complete. If a large image is to be loaded, it may be
+ preferable to load the image in a low priority thread, by enabling the \l asynchronous
+ property.
- Images are cached and shared internally, so if several Image elements have the same source
+ If the image is from a network rather than a local resource, it is automatically loaded
+ asynchronously, and the \l progress and \l status properties are updated as appropriate.
+
+ Images are cached and shared internally, so if several Image elements have the same \l source,
only one copy of the image will be loaded.
\bold Note: Images are often the greatest user of memory in QML user interfaces. It is recommended
@@ -84,7 +86,7 @@ QT_BEGIN_NAMESPACE
size bounded via the \l sourceSize property. This is especially important for content
that is loaded from external sources or provided by the user.
- \sa {declarative/imageelements/image}{Image example}
+ \sa {declarative/imageelements/image}{Image example}, QDeclarativeImageProvider
*/
/*!
@@ -114,19 +116,10 @@ QDeclarativeImage::~QDeclarativeImage()
{
}
-/*!
- \qmlproperty QPixmap Image::pixmap
-
- This property holds the QPixmap image to display.
-
- This is useful for displaying images provided by a C++ implementation,
- for example, a model may provide a data role of type QPixmap.
-*/
-
QPixmap QDeclarativeImage::pixmap() const
{
Q_D(const QDeclarativeImage);
- return d->pix;
+ return d->pix.pixmap();
}
void QDeclarativeImage::setPixmap(const QPixmap &pix)
@@ -140,7 +133,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());
@@ -331,17 +324,34 @@ qreal QDeclarativeImage::paintedHeight() const
/*!
\qmlproperty QSize Image::sourceSize
- This property holds the size of the loaded image, in pixels.
+ This property holds the actual width and height of the loaded image.
+
+ Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
+ the painting of the image, this property sets the actual number of pixels
+ stored for the loaded image so that large images do not use more
+ memory than necessary. For example, this ensures the image is memory is no
+ larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
+ \l {Item::}{height} values:
+
+ \code
+ Rectangle {
+ width: ...
+ height: ...
- This is used to control the storage used by a loaded image. Unlike
- the width and height properties, which scale the painting of the image, this property
- affects the number of pixels stored.
+ Image {
+ anchors.fill: parent
+ source: "reallyBigImage.jpg"
+ sourceSize.width: 1024
+ sourceSize.height: 1024
+ }
+ }
+ \endcode
If the image's actual size is larger than the sourceSize, the image is scaled down.
If only one dimension of the size is set to greater than 0, the
other dimension is set in proportion to preserve the source image's aspect ratio.
(The \l fillMode is independent of this.)
-
+
If the source is an instrinsically scalable image (eg. SVG), this property
determines the size of the loaded image regardless of intrinsic size.
Avoid changing this property dynamically; rendering an SVG is \e slow compared
@@ -351,34 +361,8 @@ qreal QDeclarativeImage::paintedHeight() const
be no greater than this property specifies. For some formats (currently only JPEG),
the whole image will never actually be loaded into memory.
- \note \e{Changing this property dynamically will lead to the image source being reloaded,
- potentially even from the network if it is not in the disk cache.}
-
- Here is an example that ensures the size of the image in memory is
- no larger than 1024x1024 pixels, regardless of the size of the Image element.
-
- \code
- Image {
- anchors.fill: parent
- source: "images/reallyBigImage.jpg"
- sourceSize.width: 1024
- sourceSize.height: 1024
- }
- \endcode
-
- The example below ensures the memory used by the image is no more than necessary
- to display the image at the size of the Image element.
- Of course if the Image element is resized a costly reload will be required, so
- use this technique \e only when the Image size is fixed.
-
- \code
- Image {
- anchors.fill: parent
- source: "images/reallyBigImage.jpg"
- sourceSize.width: width
- sourceSize.height: height
- }
- \endcode
+ \note \e {Changing this property dynamically causes the image source to be reloaded,
+ potentially even from the network, if it is not in the disk cache.}
*/
void QDeclarativeImage::updatePaintedGeometry()
@@ -422,6 +406,8 @@ void QDeclarativeImage::geometryChanged(const QRectF &newGeometry, const QRectF
Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
The URL may be absolute, or relative to the URL of the component.
+
+ \sa QDeclarativeImageProvider
*/
/*!
@@ -431,7 +417,7 @@ void QDeclarativeImage::geometryChanged(const QRectF &newGeometry, const QRectF
asynchronously in a separate thread. The default value is
false, causing the user interface thread to block while the
image is loaded. Setting \a asynchronous to true is useful where
- maintaining a responsive user interface is more desireable
+ maintaining a responsive user interface is more desirable
than having images immediately visible.
Note that this property is only valid for images read from the
@@ -522,7 +508,6 @@ void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWi
void QDeclarativeImage::pixmapChange()
{
updatePaintedGeometry();
- emit pixmapChanged();
}
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeimage_p.h b/src/declarative/graphicsitems/qdeclarativeimage_p.h
index a4f4475..c8bb30b 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimage_p.h
@@ -57,7 +57,6 @@ class Q_AUTOTEST_EXPORT QDeclarativeImage : public QDeclarativeImageBase
Q_OBJECT
Q_ENUMS(FillMode)
- Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap NOTIFY pixmapChanged DESIGNABLE false)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedGeometryChanged)
Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
@@ -79,7 +78,6 @@ public:
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
Q_SIGNALS:
- void pixmapChanged();
void fillModeChanged();
void paintedGeometryChanged();
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 70874f2..b9498f1 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -1581,7 +1581,7 @@ QDeclarativeItem *QDeclarativeItem::parentItem() const
Returns true if construction of the QML component is complete; otherwise
returns false.
- It is often desireable to delay some processing until the component is
+ It is often desirable to delay some processing until the component is
completed.
\sa componentComplete()
@@ -1589,7 +1589,7 @@ QDeclarativeItem *QDeclarativeItem::parentItem() const
bool QDeclarativeItem::isComponentComplete() const
{
Q_D(const QDeclarativeItem);
- return d->_componentComplete;
+ return d->componentComplete;
}
void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
@@ -1730,7 +1730,7 @@ QRectF QDeclarativeItem::childrenRect()
Q_D(QDeclarativeItem);
if (!d->_contents) {
d->_contents = new QDeclarativeContents(this);
- if (d->_componentComplete)
+ if (d->componentComplete)
d->_contents->complete();
}
return d->_contents->rectF();
@@ -2085,7 +2085,7 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
relationship with other items.
Margins apply to top, bottom, left, right, and fill anchors.
- The margins property can be used to set all of the various margins at once, to the same value.
+ The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
Offsets apply for horizontal center, vertical center, and baseline anchors.
@@ -2120,10 +2120,12 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
\endqml
\endtable
- anchors.fill provides a convenient way for one item to have the
+ \c anchors.fill provides a convenient way for one item to have the
same geometry as another item, and is equivalent to connecting all
four directional anchors.
+ To clear an anchor value, set it to \c undefined.
+
\note You can only anchor an item to siblings or a parent.
For more information see \l {anchor-layout}{Anchor Layouts}.
@@ -2133,7 +2135,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.
@@ -2142,19 +2144,19 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
qreal QDeclarativeItem::baselineOffset() const
{
Q_D(const QDeclarativeItem);
- if (!d->_baselineOffset.isValid()) {
+ if (!d->baselineOffset.isValid()) {
return 0.0;
} else
- return d->_baselineOffset;
+ return d->baselineOffset;
}
void QDeclarativeItem::setBaselineOffset(qreal offset)
{
Q_D(QDeclarativeItem);
- if (offset == d->_baselineOffset)
+ if (offset == d->baselineOffset)
return;
- d->_baselineOffset = offset;
+ d->baselineOffset = offset;
for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
@@ -2283,7 +2285,7 @@ void QDeclarativeItem::setBaselineOffset(qreal offset)
bool QDeclarativeItem::keepMouseGrab() const
{
Q_D(const QDeclarativeItem);
- return d->_keepMouse;
+ return d->keepMouse;
}
/*!
@@ -2307,7 +2309,7 @@ bool QDeclarativeItem::keepMouseGrab() const
void QDeclarativeItem::setKeepMouseGrab(bool keep)
{
Q_D(QDeclarativeItem);
- d->_keepMouse = keep;
+ d->keepMouse = keep;
}
/*!
@@ -2404,6 +2406,8 @@ QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const
void QDeclarativeItemPrivate::focusChanged(bool flag)
{
Q_Q(QDeclarativeItem);
+ if (!(flags & QGraphicsItem::ItemIsFocusScope) && parent)
+ emit q->wantsFocusChanged(flag); //see also QDeclarativeItemPrivate::subFocusItemChange()
emit q->focusChanged(flag);
}
@@ -2487,7 +2491,7 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi
\qmlproperty bool Item::clip
This property holds whether clipping is enabled.
- if clipping is enabled, an item will clip its own painting, as well
+ If clipping is enabled, an item will clip its own painting, as well
as the painting of its children, to its bounding rectangle.
Non-rectangular clipping regions are not supported for performance reasons.
@@ -2568,7 +2572,7 @@ QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform()
void QDeclarativeItem::classBegin()
{
Q_D(QDeclarativeItem);
- d->_componentComplete = false;
+ d->componentComplete = false;
if (d->_stateGroup)
d->_stateGroup->classBegin();
if (d->_anchors)
@@ -2579,14 +2583,14 @@ void QDeclarativeItem::classBegin()
\internal
componentComplete() is called when all items in the component
- have been constructed. It is often desireable to delay some
+ have been constructed. It is often desirable to delay some
processing until the component is complete an all bindings in the
component have been resolved.
*/
void QDeclarativeItem::componentComplete()
{
Q_D(QDeclarativeItem);
- d->_componentComplete = true;
+ d->componentComplete = true;
if (d->_stateGroup)
d->_stateGroup->componentComplete();
if (d->_anchors) {
@@ -2604,7 +2608,7 @@ QDeclarativeStateGroup *QDeclarativeItemPrivate::_states()
Q_Q(QDeclarativeItem);
if (!_stateGroup) {
_stateGroup = new QDeclarativeStateGroup;
- if (!_componentComplete)
+ if (!componentComplete)
_stateGroup->classBegin();
QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
q, SIGNAL(stateChanged(QString)));
@@ -3105,7 +3109,10 @@ void QDeclarativeItem::setSize(const QSizeF &size)
/*! \internal */
bool QDeclarativeItem::wantsFocus() const
{
- return focusItem() != 0;
+ Q_D(const QDeclarativeItem);
+ return focusItem() == this ||
+ (d->flags & QGraphicsItem::ItemIsFocusScope && focusItem() != 0) ||
+ (!parentItem() && focusItem() != 0);
}
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index fb416c2..bc5d809 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -120,11 +120,11 @@ class Q_DECLARATIVE_EXPORT QDeclarativeItemPrivate : public QGraphicsItemPrivate
public:
QDeclarativeItemPrivate()
: _anchors(0), _contents(0),
- _baselineOffset(0),
+ baselineOffset(0),
_anchorLines(0),
_stateGroup(0), origin(QDeclarativeItem::Center),
widthValid(false), heightValid(false),
- _componentComplete(true), _keepMouse(false),
+ componentComplete(true), keepMouse(false),
smooth(false), transformOriginDirty(true), doneEventPreHandler(false), keyHandler(0),
mWidth(0), mHeight(0), implicitWidth(0), implicitHeight(0)
{
@@ -144,12 +144,10 @@ public:
QDeclarative_setParent_noEvent(q, parent);
q->setParentItem(parent);
}
- _baselineOffset.invalidate();
+ baselineOffset.invalidate();
mouseSetsFocus = false;
}
- QString _id;
-
// Private Properties
qreal width() const;
void setWidth(qreal);
@@ -203,7 +201,7 @@ public:
if (!_anchors) {
Q_Q(QDeclarativeItem);
_anchors = new QDeclarativeAnchors(q);
- if (!_componentComplete)
+ if (!componentComplete)
_anchors->classBegin();
}
return _anchors;
@@ -211,7 +209,7 @@ public:
QDeclarativeAnchors *_anchors;
QDeclarativeContents *_contents;
- QDeclarativeNullableValue<qreal> _baselineOffset;
+ QDeclarativeNullableValue<qreal> baselineOffset;
struct AnchorLines {
AnchorLines(QGraphicsObject *);
@@ -260,8 +258,8 @@ public:
QDeclarativeItem::TransformOrigin origin:4;
bool widthValid:1;
bool heightValid:1;
- bool _componentComplete:1;
- bool _keepMouse:1;
+ bool componentComplete:1;
+ bool keepMouse:1;
bool smooth:1;
bool transformOriginDirty : 1;
bool doneEventPreHandler : 1;
@@ -286,7 +284,9 @@ public:
// Reimplemented from QGraphicsItemPrivate
virtual void subFocusItemChange()
{
- emit q_func()->wantsFocusChanged(subFocusItem != 0);
+ if (flags & QGraphicsItem::ItemIsFocusScope || !parent)
+ emit q_func()->wantsFocusChanged(subFocusItem != 0);
+ //see also QDeclarativeItemPrivate::focusChanged
}
// Reimplemented from QGraphicsItemPrivate
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index e519bd9..fa422fd 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -494,7 +494,7 @@ public:
QSmoothedAnimation *highlightSizeAnimator;
QDeclarativeViewSection *sectionCriteria;
QString currentSection;
- static const int sectionCacheSize = 3;
+ static const int sectionCacheSize = 4;
QDeclarativeItem *sectionCache[sectionCacheSize];
qreal spacing;
qreal highlightMoveSpeed;
@@ -1029,6 +1029,11 @@ void QDeclarativeListViewPrivate::updateCurrent(int modelIndex)
}
currentItem->item->setFocus(true);
currentItem->attached->setIsCurrentItem(true);
+ // Avoid showing section delegate twice. We still need the section heading so that
+ // currentItem positioning works correctly.
+ // This is slightly sub-optimal, but section heading caching minimizes the impact.
+ if (currentItem->section)
+ currentItem->section->setVisible(false);
}
updateHighlight();
emit q->currentIndexChanged();
@@ -1072,7 +1077,7 @@ void QDeclarativeListViewPrivate::updateFooter()
}
if (footer) {
if (visibleItems.count()) {
- qreal endPos = endPosition();
+ qreal endPos = endPosition() + 1;
if (lastVisibleIndex() == model->count()-1) {
footer->setPosition(endPos);
} else {
@@ -1547,6 +1552,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 +1619,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 +1649,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;
@@ -1720,7 +1732,7 @@ void QDeclarativeListView::setHighlight(QDeclarativeComponent *highlight)
highlight is not moved by the view, and any movement must be implemented
by the highlight.
- Here is a highlight with its motion defined by a \l {SpringFollow} item:
+ Here is a highlight with its motion defined by a \l {SpringAnimation} item:
\snippet doc/src/snippets/declarative/listview/listview.qml highlightFollowsCurrentItem
@@ -2439,7 +2451,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 +2469,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 +2601,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 +2621,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 +2645,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 +2660,12 @@ void QDeclarativeListView::trackedPositionChanged()
if (d->currentItem->size() > d->size())
pos = d->currentItem->position();
}
- d->setPosition(pos);
}
}
+ if (viewPos != pos) {
+ cancelFlick();
+ d->setPosition(pos);
+ }
}
}
@@ -2885,8 +2893,11 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
d->visiblePos = d->header ? d->header->size() : 0;
d->timeline.clear();
d->setPosition(0);
- if (d->itemCount == 0)
+ if (d->itemCount == 0) {
+ d->updateHeader();
+ d->updateFooter();
update();
+ }
}
emit countChanged();
@@ -3021,6 +3032,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/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index caf251d..b7b0c9e 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -443,7 +443,7 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QPointF startLocalPos;
QPointF curLocalPos;
- if (drag()->target()->parent()) {
+ if (drag()->target()->parentItem()) {
startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
curLocalPos = drag()->target()->parentItem()->mapFromScene(event->scenePos());
} else {
@@ -761,16 +761,22 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag()
\c drag provides a convenient way to make an item draggable.
\list
- \i \c drag.target specifies the item to drag.
+ \i \c drag.target specifies the id of the item to drag.
\i \c drag.active specifies if the target item is currently being dragged.
\i \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XandYAxis)
\i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
\endlist
- The following example displays an image that can be dragged along the X-axis. The opacity
- of the image is reduced when it is dragged to the right.
+ The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
+ of the rectangle is reduced when it is dragged to the right.
\snippet doc/src/snippets/declarative/mousearea.qml drag
+
+ \note Items cannot be dragged if they are anchored for the requested
+ \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
+ for \c rect in the above example, it cannot be dragged along the X-axis.
+ This can be avoided by settng the anchor value to \c undefined in
+ an \l onPressed handler.
*/
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 0e980b3..f4ebd13 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -329,6 +329,10 @@ void QDeclarativePathViewPrivate::regenerate()
\image pathview.gif
+ (Note the above example uses PathAttribute to scale and modify the
+ opacity of the items as they rotate. This additional code can be seen in the
+ PathAttribute documentation.)
+
Delegates are instantiated as needed and may be destroyed at any time.
State should \e never be stored in a delegate.
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..ba4fa21 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:
@@ -730,7 +772,7 @@ void QDeclarativeText::geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry)
{
Q_D(QDeclarativeText);
- if (newGeometry.width() != oldGeometry.width()) {
+ if (!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width()) {
if (d->wrapMode != QDeclarativeText::NoWrap || d->elideMode != QDeclarativeText::ElideNone) {
//re-elide if needed
if (d->singleline && d->elideMode != QDeclarativeText::ElideNone &&
@@ -830,7 +872,9 @@ void QDeclarativeTextPrivate::updateSize()
q->setBaselineOffset(fm.ascent() + yoff);
//### need to comfirm cost of always setting these for richText
+ internalWidthUpdate = true;
q->setImplicitWidth(size.width());
+ internalWidthUpdate = false;
q->setImplicitHeight(size.height());
emit q->paintedSizeChanged();
} else {
@@ -1074,20 +1118,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.
*/
@@ -1097,6 +1127,15 @@ int QDeclarativeText::resourcesLoading() const
return d->doc ? d->doc->resourcesLoading() : 0;
}
+/*!
+ \qmlproperty bool Text::clip
+ This property holds whether the text is clipped.
+
+ Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
+
+ If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
+*/
+
void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QDeclarativeText);
@@ -1116,13 +1155,10 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
bool needClip = clip() && (d->imgCache.width() > width() ||
d->imgCache.height() > height());
- if (needClip) {
- p->save();
- p->setClipRect(boundingRect(), Qt::IntersectClip);
- }
- p->drawPixmap(br.x(), br.y(), d->imgCache);
if (needClip)
- p->restore();
+ p->drawPixmap(0, 0, width(), height(), d->imgCache, -br.x(), -br.y(), width(), height());
+ else
+ p->drawPixmap(br.x(), br.y(), d->imgCache);
if (d->smooth) {
p->setRenderHint(QPainter::Antialiasing, oldAA);
@@ -1136,7 +1172,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
if (needClip) {
p->save();
- p->setClipRect(boundingRect(), Qt::IntersectClip);
+ p->setClipRect(0, 0, width(), height(), Qt::IntersectClip);
}
if (d->richText) {
QAbstractTextDocumentLayout::PaintContext context;
@@ -1173,11 +1209,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..48552a7 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
@@ -72,7 +72,7 @@ public:
QDeclarativeTextPrivate()
: color((QRgb)0), style(QDeclarativeText::Normal),
hAlign(QDeclarativeText::AlignLeft), vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone),
- imgDirty(true), dirty(true), richText(false), singleline(false), cache(true), doc(0),
+ imgDirty(true), dirty(true), richText(false), singleline(false), cache(true), internalWidthUpdate(false), doc(0),
format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap)
{
#if defined(QML_NO_TEXT_CACHE)
@@ -119,11 +119,16 @@ public:
bool richText:1;
bool singleline:1;
bool cache:1;
+ bool internalWidthUpdate:1;
QTextDocumentWithImageResources *doc;
QTextLayout layout;
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 3f179da..d13e139 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -1264,6 +1264,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()));
@@ -1333,6 +1342,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);
}
@@ -1372,12 +1390,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..2a5d73d 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();
}
/*!
@@ -277,6 +275,8 @@ void QDeclarativeTextInput::setSelectionColor(const QColor &color)
QPalette p = d->control->palette();
p.setColor(QPalette::Highlight, d->selectionColor);
d->control->setPalette(p);
+ clearCache();
+ update();
emit selectionColorChanged(color);
}
@@ -301,6 +301,8 @@ void QDeclarativeTextInput::setSelectedTextColor(const QColor &color)
QPalette p = d->control->palette();
p.setColor(QPalette::HighlightedText, d->selectedTextColor);
d->control->setPalette(p);
+ clearCache();
+ update();
emit selectedTextColorChanged(color);
}
@@ -550,9 +552,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 +828,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 +912,7 @@ void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev)
void QDeclarativeTextInput::inputMethodEvent(QInputMethodEvent *ev)
{
Q_D(QDeclarativeTextInput);
+ ev->ignore();
inputMethodPreHandler(ev);
if (ev->isAccepted())
return;
@@ -1020,27 +1023,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 +1057,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 +1076,6 @@ void QDeclarativeTextInputPrivate::updateHorizontalScroll()
} else {
hscroll = 0;
}
- hscroll -= minLB;
}
}
@@ -1095,7 +1100,6 @@ void QDeclarativeTextInput::drawContents(QPainter *p, const QRect &r)
offset = QPoint(d->hscroll, 0);
}
d->control->draw(p, offset, r, flags);
-
p->restore();
}
@@ -1142,6 +1146,42 @@ void QDeclarativeTextInput::selectAll()
d->control->setSelection(0, d->control->text().length());
}
+#ifndef QT_NO_CLIPBOARD
+/*!
+ \qmlmethod TextInput::cut()
+
+ Moves the currently selected text to the system clipboard.
+*/
+void QDeclarativeTextInput::cut()
+{
+ Q_D(QDeclarativeTextInput);
+ d->control->copy();
+ d->control->del();
+}
+
+/*!
+ \qmlmethod TextInput::copy()
+
+ Copies the currently selected text to the system clipboard.
+*/
+void QDeclarativeTextInput::copy()
+{
+ Q_D(QDeclarativeTextInput);
+ d->control->copy();
+}
+
+/*!
+ \qmlmethod TextInput::paste()
+
+ Replaces the currently selected text by the contents of the system clipboard.
+*/
+void QDeclarativeTextInput::paste()
+{
+ Q_D(QDeclarativeTextInput);
+ d->control->paste();
+}
+#endif // QT_NO_CLIPBOARD
+
/*!
\qmlmethod void TextInput::selectWord()
@@ -1448,8 +1488,8 @@ void QDeclarativeTextInput::selectionChanged()
void QDeclarativeTextInput::q_textChanged()
{
Q_D(QDeclarativeTextInput);
- d->updateHorizontalScroll();
updateSize();
+ d->updateHorizontalScroll();
updateMicroFocus();
emit textChanged();
emit displayTextChanged();
@@ -1469,16 +1509,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..b1862c6 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();
@@ -230,6 +232,11 @@ public Q_SLOTS:
void selectAll();
void selectWord();
void select(int start, int end);
+#ifndef QT_NO_CLIPBOARD
+ void cut();
+ void copy();
+ void paste();
+#endif
private Q_SLOTS:
void updateSize(bool needsRedraw = true);
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;