Update SG items with GV item changes.
authorMartin Jones <martin.jones@nokia.com>
Wed, 4 May 2011 07:53:51 +0000 (17:53 +1000)
committerMartin Jones <martin.jones@nokia.com>
Wed, 4 May 2011 07:54:21 +0000 (17:54 +1000)
21 files changed:
src/declarative/items/qsgflickable.cpp
src/declarative/items/qsgflickable_p_p.h
src/declarative/items/qsggridview.cpp
src/declarative/items/qsgimage.cpp
src/declarative/items/qsgimagebase.cpp
src/declarative/items/qsgimagebase_p.h
src/declarative/items/qsglistview.cpp
src/declarative/items/qsgmousearea.cpp
src/declarative/items/qsgmousearea_p.h
src/declarative/items/qsgmousearea_p_p.h
src/declarative/items/qsgpathview.cpp
src/declarative/items/qsgpincharea.cpp
src/declarative/items/qsgpincharea_p.h
src/declarative/items/qsgpincharea_p_p.h
src/declarative/items/qsgtext.cpp
src/declarative/items/qsgtext_p_p.h
src/declarative/items/qsgtextedit.cpp
src/declarative/items/qsgtextinput.cpp
src/declarative/items/qsgtextinput_p.h
src/declarative/items/qsgtextinput_p_p.h
tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp

index e2f6fff..ab3559b 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: ee767e8c16742316068e83323374ea54f2b939cb
+// Commit: d4fa1878ff1e7628d3e984d54f8a93810353c71b
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 #include <QtDeclarative/qdeclarativeinfo.h>
 #include <QtGui/qgraphicssceneevent.h>
 #include <QtGui/qapplication.h>
+#include "qplatformdefs.h"
 
 QT_BEGIN_NAMESPACE
 
+// The maximum number of pixels a flick can overshoot
+#ifndef QML_FLICK_OVERSHOOT
+#define QML_FLICK_OVERSHOOT 200
+#endif
+
+// The number of samples to use in calculating the velocity of a flick
+#ifndef QML_FLICK_SAMPLEBUFFER
+#define QML_FLICK_SAMPLEBUFFER 3
+#endif
+
+// The number of samples to discard when calculating the flick velocity.
+// Touch panels often produce inaccurate results as the finger is lifted.
+#ifndef QML_FLICK_DISCARDSAMPLES
+#define QML_FLICK_DISCARDSAMPLES 1
+#endif
+
+// The default maximum velocity of a flick.
+#ifndef QML_FLICK_DEFAULTMAXVELOCITY
+#define QML_FLICK_DEFAULTMAXVELOCITY 2500
+#endif
+
+// The default deceleration of a flick.
+#ifndef QML_FLICK_DEFAULTDECELERATION
+#define QML_FLICK_DEFAULTDECELERATION 1500
+#endif
+
+// How much faster to decelerate when overshooting
+#ifndef QML_FLICK_OVERSHOOTFRICTION
+#define QML_FLICK_OVERSHOOTFRICTION 8
+#endif
+
 // FlickThreshold determines how far the "mouse" must have moved
 // before we perform a flick.
 static const int FlickThreshold = 20;
@@ -143,8 +175,9 @@ QSGFlickablePrivate::QSGFlickablePrivate()
     , hMoved(false), vMoved(false)
     , movingHorizontally(false), movingVertically(false)
     , stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
-    , deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100)
-    , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600)
+    , deceleration(QML_FLICK_DEFAULTDECELERATION)
+    , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
+    , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400)
     , fixupMode(Normal), vTime(0), visibleArea(0)
     , flickableDirection(QSGFlickable::AutoFlickDirection)
     , boundsBehavior(QSGFlickable::DragAndOvershootBounds)
@@ -181,16 +214,36 @@ void QSGFlickablePrivate::init()
     Returns the amount to overshoot by given a velocity.
     Will be roughly in range 0 - size/4
 */
-qreal QSGFlickablePrivate::overShootDistance(qreal velocity, qreal size)
+qreal QSGFlickablePrivate::overShootDistance(qreal size)
 {
     if (maxVelocity <= 0)
         return 0.0;
 
-    velocity = qAbs(velocity);
-    if (velocity > maxVelocity)
-        velocity = maxVelocity;
-    qreal dist = size / 4 * velocity / maxVelocity;
-    return dist;
+    return qMin(qreal(QML_FLICK_OVERSHOOT), size/3);
+}
+
+void QSGFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity)
+{
+    if (v > maxVelocity)
+        v = maxVelocity;
+    else if (v < -maxVelocity)
+        v = -maxVelocity;
+    velocityBuffer.append(v);
+    if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER)
+        velocityBuffer.remove(0);
+}
+
+void QSGFlickablePrivate::AxisData::updateVelocity()
+{
+    if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) {
+        velocity = 0;
+        int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES;
+        for (int i = 0; i < count; ++i) {
+            qreal v = velocityBuffer.at(i);
+            velocity += v;
+        }
+        velocity /= count;
+    }
 }
 
 void QSGFlickablePrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeom, const QRectF &oldGeom)
@@ -216,21 +269,18 @@ void QSGFlickablePrivate::flickY(qreal velocity)
     flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity);
 }
 
-void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal,
                                          QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
 {
     Q_Q(QSGFlickable);
     qreal maxDistance = -1;
     data.fixingUp = false;
-    bool overShoot = boundsBehavior == QSGFlickable::DragAndOvershootBounds;
     // -ve velocity means list is moving up
     if (velocity > 0) {
-        if (data.move.value() < minExtent)
-            maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity,vSize):0));
+        maxDistance = qAbs(minExtent - data.move.value());
         data.flickTarget = minExtent;
     } else {
-        if (data.move.value() > maxExtent)
-            maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity,vSize):0);
+        maxDistance = qAbs(maxExtent - data.move.value());
         data.flickTarget = maxExtent;
     }
     if (maxDistance > 0) {
@@ -242,7 +292,10 @@ void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent
                 v = maxVelocity;
         }
         timeline.reset(data.move);
-        timeline.accel(data.move, v, deceleration, maxDistance);
+        if (boundsBehavior == QSGFlickable::DragAndOvershootBounds)
+            timeline.accel(data.move, v, deceleration);
+        else
+            timeline.accel(data.move, v, deceleration, maxDistance);
         timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
         if (!flickingHorizontally && q->xflick()) {
             flickingHorizontally = true;
@@ -329,6 +382,7 @@ void QSGFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent
             }
         }
     }
+    data.inOvershoot = false;
     fixupMode = Normal;
     vTime = timeline.time();
 }
@@ -537,16 +591,13 @@ void QSGFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
     q->setKeepMouseGrab(stealMouse);
     pressed = true;
     timeline.clear();
-    hData.velocity = 0;
-    vData.velocity = 0;
-    hData.dragStartOffset = 0;
-    vData.dragStartOffset = 0;
+    hData.reset();
+    vData.reset();
     hData.dragMinBound = q->minXExtent();
     vData.dragMinBound = q->minYExtent();
     hData.dragMaxBound = q->maxXExtent();
     vData.dragMaxBound = q->maxYExtent();
-    hData.fixingUp = false;
-    vData.fixingUp = false;
+    fixupMode = Normal;
     lastPos = QPoint();
     QSGItemPrivate::start(lastPosTime);
     pressPos = event->pos();
@@ -638,33 +689,33 @@ void QSGFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
     if (stealMouse)
         q->setKeepMouseGrab(true);
 
-    if (!lastPos.isNull()) {
-        qreal elapsed = qreal(QSGItemPrivate::restart(lastPosTime)) / 1000.;
-        if (elapsed <= 0)
-            elapsed = 1;
-        if (q->yflick()) {
-            qreal diff = event->pos().y() - lastPos.y();
-            // average to reduce the effect of spurious moves
-            vData.velocity += diff / elapsed;
-            vData.velocity /= 2;
-        }
-
-        if (q->xflick()) {
-            qreal diff = event->pos().x() - lastPos.x();
-            // average to reduce the effect of spurious moves
-            hData.velocity += diff / elapsed;
-            hData.velocity /= 2;
-        }
+    if (rejectY) {
+        vData.velocityBuffer.clear();
+        vData.velocity = 0;
+    }
+    if (rejectX) {
+        hData.velocityBuffer.clear();
+        hData.velocity = 0;
     }
-
-    if (rejectY) vData.velocity = 0;
-    if (rejectX) hData.velocity = 0;
 
     if (hMoved || vMoved) {
         q->movementStarting();
         q->viewportMoved();
     }
 
+    if (!lastPos.isNull()) {
+        qreal elapsed = qreal(QSGItemPrivate::elapsed(lastPosTime)) / 1000.;
+        if (elapsed <= 0)
+            return;
+        QSGItemPrivate::restart(lastPosTime);
+        qreal dy = event->pos().y()-lastPos.y();
+        if (q->yflick() && !rejectY)
+            vData.addVelocitySample(dy/elapsed, maxVelocity);
+        qreal dx = event->pos().x()-lastPos.x();
+        if (q->xflick() && !rejectX)
+            hData.addVelocitySample(dx/elapsed, maxVelocity);
+    }
+
     lastPos = event->pos();
 }
 
@@ -677,25 +728,33 @@ void QSGFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *even
     if (!lastPosTime.isValid())
         return;
 
-    if (QSGItemPrivate::elapsed(lastPosTime) > 100) {
-        // if we drag then pause before release we should not cause a flick.
+    // if we drag then pause before release we should not cause a flick.
+    if (QSGItemPrivate::elapsed(lastPosTime) < 100) {
+        vData.updateVelocity();
+        hData.updateVelocity();
+    } else {
         hData.velocity = 0.0;
         vData.velocity = 0.0;
     }
 
     vTime = timeline.time();
-    if (qAbs(vData.velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold)
-        flickY(vData.velocity);
+
+    qreal velocity = vData.velocity;
+    if (vData.atBeginning || vData.atEnd)
+        velocity /= 2;
+    if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold)
+        flickY(velocity);
     else
         fixupY();
 
-    if (qAbs(hData.velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold)
-        flickX(hData.velocity);
+    velocity = hData.velocity;
+    if (hData.atBeginning || hData.atEnd)
+        velocity /= 2;
+    if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold)
+        flickX(velocity);
     else
         fixupX();
 
-    lastPosTime.invalidate();
-
     if (!timeline.isActive())
         q->movementEnding();
 }
@@ -742,29 +801,41 @@ void QSGFlickable::wheelEvent(QGraphicsSceneWheelEvent *event)
     if (!d->interactive) {
         QSGItem::wheelEvent(event);
     } else if (yflick() && event->orientation() == Qt::Vertical) {
-        if (event->delta() > 0)
-            d->vData.velocity = qMax(event->delta() - d->vData.smoothVelocity.value(), qreal(250.0));
-        else
-            d->vData.velocity = qMin(event->delta() - d->vData.smoothVelocity.value(), qreal(-250.0));
-        d->flickingVertically = false;
-        d->flickY(d->vData.velocity);
-        if (d->flickingVertically) {
-            d->vMoved = true;
-            movementStarting();
+        bool valid = false;
+        if (event->delta() > 0 && contentY() > -minYExtent()) {
+            d->vData.velocity = qMax(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4));
+            valid = true;
+        } else if (event->delta() < 0 && contentY() < -maxYExtent()) {
+            d->vData.velocity = qMin(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
+            valid = true;
+        }
+        if (valid) {
+            d->flickingVertically = false;
+            d->flickY(d->vData.velocity);
+            if (d->flickingVertically) {
+                d->vMoved = true;
+                movementStarting();
+            }
+            event->accept();
         }
-        event->accept();
     } else if (xflick() && event->orientation() == Qt::Horizontal) {
-        if (event->delta() > 0)
-            d->hData.velocity = qMax(event->delta() - d->hData.smoothVelocity.value(), qreal(250.0));
-        else
-            d->hData.velocity = qMin(event->delta() - d->hData.smoothVelocity.value(), qreal(-250.0));
-        d->flickingHorizontally = false;
-        d->flickX(d->hData.velocity);
-        if (d->flickingHorizontally) {
-            d->hMoved = true;
-            movementStarting();
+        bool valid = false;
+        if (event->delta() > 0 && contentX() > -minXExtent()) {
+            d->hData.velocity = qMax(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4));
+            valid = true;
+        } else if (event->delta() < 0 && contentX() < -maxXExtent()) {
+            d->hData.velocity = qMin(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
+            valid = true;
+        }
+        if (valid) {
+            d->flickingHorizontally = false;
+            d->flickX(d->hData.velocity);
+            if (d->flickingHorizontally) {
+                d->hMoved = true;
+                movementStarting();
+            }
+            event->accept();
         }
-        event->accept();
     } else {
         QSGItem::wheelEvent(event);
     }
@@ -901,6 +972,27 @@ void QSGFlickable::viewportMoved()
         }
     }
 
+    if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically
+            && (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent())
+            && qAbs(d->vData.smoothVelocity.value()) > 100) {
+        // Increase deceleration if we've passed a bound
+        d->vData.inOvershoot = true;
+        qreal maxDistance = d->overShootDistance(height());
+        d->timeline.reset(d->vData.move);
+        d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
+        d->timeline.callback(QDeclarativeTimeLineCallback(&d->vData.move, d->fixupY_callback, d));
+    }
+    if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally
+            && (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent())
+            && qAbs(d->hData.smoothVelocity.value()) > 100) {
+        // Increase deceleration if we've passed a bound
+        d->hData.inOvershoot = true;
+        qreal maxDistance = d->overShootDistance(width());
+        d->timeline.reset(d->hData.move);
+        d->timeline.accel(d->hData.move, -d->hData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
+        d->timeline.callback(QDeclarativeTimeLineCallback(&d->hData.move, d->fixupX_callback, d));
+    }
+
     d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value());
 
     d->vTime = d->timeline.time();
@@ -1071,7 +1163,9 @@ void QSGFlickable::resizeContent(qreal w, qreal h, QPointF center)
     Q_D(QSGFlickable);
     if (w != d->hData.viewSize) {
         qreal oldSize = d->hData.viewSize;
-        setContentWidth(w);
+        d->hData.viewSize = w;
+        d->contentItem->setWidth(w);
+        emit contentWidthChanged();
         if (center.x() != 0) {
             qreal pos = center.x() * w / oldSize;
             setContentX(contentX() + pos - center.x());
@@ -1079,12 +1173,15 @@ void QSGFlickable::resizeContent(qreal w, qreal h, QPointF center)
     }
     if (h != d->vData.viewSize) {
         qreal oldSize = d->vData.viewSize;
-        setContentHeight(h);
+        d->vData.viewSize = h;
+        d->contentItem->setHeight(h);
+        emit contentHeightChanged();
         if (center.y() != 0) {
             qreal pos = center.y() * h / oldSize;
             setContentY(contentY() + pos - center.y());
         }
     }
+    d->updateBeginningEnd();
 }
 
 void QSGFlickable::returnToBounds()
@@ -1148,8 +1245,9 @@ bool QSGFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
 
     QSGCanvas *c = canvas();
     QSGItem *grabber = c ? c->mouseGrabberItem() : 0;
+    bool disabledItem = grabber && !grabber->isEnabled();
     bool stealThisEvent = d->stealMouse;
-    if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
+    if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab() || disabledItem)) {
         mouseEvent.setAccepted(false);
         for (int i = 0x1; i <= 0x10; i <<= 1) {
             if (event->buttons() & i) {
@@ -1196,12 +1294,12 @@ bool QSGFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
             break;
         }
         grabber = qobject_cast<QSGItem*>(c->mouseGrabberItem());
-        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) {
+        if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || disabledItem) {
             d->clearDelayedPress();
             grabMouse();
         }
 
-        return stealThisEvent || d->delayedPressEvent;
+        return stealThisEvent || d->delayedPressEvent || disabledItem;
     } else if (d->lastPosTime.isValid()) {
         d->lastPosTime.invalidate();
     }
index 2861bfd..9f212ee 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: cb0a6844705802564c81b581f24a76c5d5adf6d1
+// Commit: 160f1867868cdea916923652b00484ed11f90aaa
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -96,9 +96,19 @@ public:
     struct AxisData {
         AxisData(QSGFlickablePrivate *fp, void (QSGFlickablePrivate::*func)(qreal))
             : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true)
-            , fixingUp(false)
+            , fixingUp(false), inOvershoot(false)
         {}
 
+        void reset() {
+            velocityBuffer.clear();
+            dragStartOffset = 0;
+            fixingUp = false;
+            inOvershoot = false;
+        }
+
+        void addVelocitySample(qreal v, qreal maxVelocity);
+        void updateVelocity();
+
         QDeclarativeTimeLineValueProxy<QSGFlickablePrivate> move;
         qreal viewSize;
         qreal pressPos;
@@ -108,9 +118,11 @@ public:
         qreal velocity;
         qreal flickTarget;
         QSGFlickablePrivate::Velocity smoothVelocity;
+        QPODVector<qreal,10> velocityBuffer;
         bool atEnd : 1;
         bool atBeginning : 1;
         bool fixingUp : 1;
+        bool inOvershoot : 1;
     };
 
     void flickX(qreal velocity);
@@ -131,7 +143,7 @@ public:
     void setRoundedViewportX(qreal x);
     void setRoundedViewportY(qreal y);
 
-    qreal overShootDistance(qreal velocity, qreal size);
+    qreal overShootDistance(qreal size);
 
     void itemGeometryChanged(QSGItem *, const QRectF &, const QRectF &);
 
index 4f00d36..43f7f98 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: cc6408ccd5453d1bed9f98b9caa14861cea5742b
+// Commit: fda9cc1d8a0e49817d1c6192c52d18dffcecf327
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -581,6 +581,26 @@ void QSGGridViewPrivate::refill(qreal from, qreal to, bool doBuffer)
             --i;
         modelIndex = visibleItems.at(i)->index + 1;
     }
+
+    if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2
+        || fillTo < rowPosAt(visibleIndex) - rowSize())) {
+        // We've jumped more than a page.  Estimate which items are now
+        // visible and fill from there.
+        int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
+        for (int i = 0; i < visibleItems.count(); ++i)
+            releaseItem(visibleItems.at(i));
+        visibleItems.clear();
+        modelIndex += count;
+        if (modelIndex >= model->count())
+            modelIndex = model->count() - 1;
+        else if (modelIndex < 0)
+            modelIndex = 0;
+        modelIndex = modelIndex / columns * columns;
+        visibleIndex = modelIndex;
+        colPos = colPosAt(visibleIndex);
+        rowPos = rowPosAt(visibleIndex);
+    }
+
     int colNum = colPos / colSize();
 
     FxGridItemSG *item = 0;
@@ -1112,6 +1132,7 @@ void QSGGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
     } else {
         QSGFlickablePrivate::fixup(data, minExtent, maxExtent);
     }
+    data.inOvershoot = false;
     fixupMode = Normal;
 }
 
@@ -1190,7 +1211,7 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
             accel = v2 / (2.0f * qAbs(dist));
         } else {
             data.flickTarget = velocity > 0 ? minExtent : maxExtent;
-            overshootDist = overShoot ? overShootDistance(v, vSize) : 0;
+            overshootDist = overShoot ? overShootDistance(vSize) : 0;
         }
         timeline.reset(data.move);
         timeline.accel(data.move, v, accel, maxDistance + overshootDist);
@@ -1869,7 +1890,7 @@ qreal QSGGridView::maxXExtent() const
     qreal extent;
     qreal highlightStart;
     qreal highlightEnd;
-    qreal lastItemPosition;
+    qreal lastItemPosition = 0;
     if (d->isRightToLeftTopToBottom()){
         highlightStart = d->highlightRangeStartValid ? d->highlightRangeEnd : d->size();
         highlightEnd = d->highlightRangeEndValid ? d->highlightRangeStart : d->size();
@@ -1877,6 +1898,7 @@ qreal QSGGridView::maxXExtent() const
     } else {
         highlightStart = d->highlightRangeStart;
         highlightEnd = d->highlightRangeEnd;
+        lastItemPosition = 0;
         if (d->model && d->model->count())
             lastItemPosition = d->rowPosAt(d->model->count()-1);
     }
@@ -2367,11 +2389,9 @@ void QSGGridView::itemsInserted(int modelIndex, int count)
         if (d->currentItem) {
             d->currentItem->index = d->currentIndex;
             d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex));
-        } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) {
-            d->updateCurrent(0);
         }
         emit currentIndexChanged();
-    } else if (d->itemCount == 0 && d->currentIndex == -1) {
+    } else if (d->itemCount == 0 && (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared))) {
         setCurrentIndex(0);
     }
 
@@ -2439,6 +2459,8 @@ void QSGGridView::itemsRemoved(int modelIndex, int count)
         d->currentIndex = -1;
         if (d->itemCount)
             d->updateCurrent(qMin(modelIndex, d->itemCount-1));
+        else
+            emit currentIndexChanged();
     }
 
     // update visibleIndex
index d24db9f..10670f4 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 695a39410c8ce186a2ce78cef51093c55fc32643
+// Commit: 051a76c1d65d698f71dc75c89f91ae9021357eae
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -77,12 +77,10 @@ void QSGImagePrivate::setPixmap(const QPixmap &pixmap)
     Q_Q(QSGImage);
     pix.setPixmap(pixmap);
 
-    q->setImplicitWidth(pix.width());
-    q->setImplicitHeight(pix.height());
+    q->pixmapChange();
     status = pix.isNull() ? QSGImageBase::Null : QSGImageBase::Ready;
 
     q->update();
-    q->pixmapChange();
 }
 
 QSGImage::FillMode QSGImage::fillMode() const
@@ -119,8 +117,11 @@ void QSGImage::updatePaintedGeometry()
     Q_D(QSGImage);
 
     if (d->fillMode == PreserveAspectFit) {
-        if (!d->pix.width() || !d->pix.height())
+        if (!d->pix.width() || !d->pix.height()) {
+            setImplicitWidth(0);
+            setImplicitHeight(0);
             return;
+        }
         qreal w = widthValid() ? width() : d->pix.width();
         qreal widthScale = w / qreal(d->pix.width());
         qreal h = heightValid() ? height() : d->pix.height();
@@ -134,9 +135,13 @@ void QSGImage::updatePaintedGeometry()
         }
         if (widthValid() && !heightValid()) {
             setImplicitHeight(d->paintedHeight);
+        } else {
+            setImplicitHeight(d->pix.height());
         }
         if (heightValid() && !widthValid()) {
             setImplicitWidth(d->paintedWidth);
+        } else {
+            setImplicitWidth(d->pix.width());
         }
     } else if (d->fillMode == PreserveAspectCrop) {
         if (!d->pix.width() || !d->pix.height())
@@ -280,7 +285,12 @@ QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
 void QSGImage::pixmapChange()
 {
     Q_D(QSGImage);
-
+    // PreserveAspectFit calculates the implicit size differently so we
+    // don't call our superclass pixmapChange(), since that would
+    // result in the implicit size being set incorrectly, then updated
+    // in updatePaintedGeometry()
+    if (d->fillMode != PreserveAspectFit)
+        QSGImageBase::pixmapChange();
     updatePaintedGeometry();
     d->pixmapChanged = true;
 }
index bd8b24f..9f2de03 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 462429f5692f810bdd4e04b916db5f9af428d9e4
+// Commit: 051a76c1d65d698f71dc75c89f91ae9021357eae
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -134,6 +134,18 @@ QSize QSGImageBase::sourceSize() const
     return QSize(width != -1 ? width : d->pix.width(), height != -1 ? height : d->pix.height());
 }
 
+void QSGImageBase::resetSourceSize()
+{
+    Q_D(QSGImageBase);
+    if (!d->explicitSourceSize)
+        return;
+    d->explicitSourceSize = false;
+    d->sourcesize = QSize();
+    emit sourceSizeChanged();
+    if (isComponentComplete())
+        load();
+}
+
 bool QSGImageBase::cache() const
 {
     Q_D(const QSGImageBase);
@@ -180,11 +192,9 @@ void QSGImageBase::load()
         d->pix.clear(this);
         d->status = Null;
         d->progress = 0.0;
-        setImplicitWidth(0);
-        setImplicitHeight(0);
+        pixmapChange();
         emit progressChanged(d->progress);
         emit statusChanged(d->status);
-        pixmapChange();
         update();
     } else {
         QDeclarativePixmap::Options options;
@@ -235,8 +245,7 @@ void QSGImageBase::requestFinished()
 
     d->progress = 1.0;
 
-    setImplicitWidth(d->pix.width());
-    setImplicitHeight(d->pix.height());
+    pixmapChange();
 
     if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
         emit sourceSizeChanged();
@@ -245,7 +254,7 @@ void QSGImageBase::requestFinished()
         emit statusChanged(d->status);
     if (d->progress != oldProgress)
         emit progressChanged(d->progress);
-    pixmapChange();
+
     update();
 }
 
@@ -268,6 +277,9 @@ void QSGImageBase::componentComplete()
 
 void QSGImageBase::pixmapChange()
 {
+    Q_D(QSGImageBase);
+    setImplicitWidth(d->pix.width());
+    setImplicitHeight(d->pix.height());
 }
 
 QT_END_NAMESPACE
index fe42854..00b1452 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: ab71df83ba4eb9d749efc0f3a2d4a0fe5486023f
+// Commit: af05f64d3edc860c3cf79c7f0bdf2377faae5f40
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -60,7 +60,7 @@ class Q_AUTOTEST_EXPORT QSGImageBase : public QSGImplicitSizeItem
     Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
     Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
     Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged)
-    Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
+    Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged)
     Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
 
 public:
@@ -81,6 +81,7 @@ public:
 
     virtual void setSourceSize(const QSize&);
     QSize sourceSize() const;
+    void resetSourceSize();
 
     virtual void setMirror(bool mirror);
     bool mirror() const;
index 80cc8be..3bc9026 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: ce38c6e3a9b7eb336cbd9cd1e9520a5000c8f8ac
+// Commit: cce89db1e2555cbca8fc28072e1c6dd737cec6c4
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -743,6 +743,27 @@ void QSGListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
             modelIndex = visibleItems.at(i)->index + 1;
     }
 
+    if (visibleItems.count() && (fillFrom > itemEnd+averageSize+spacing
+        || fillTo < visiblePos - averageSize - spacing)) {
+        // We've jumped more than a page.  Estimate which items are now
+        // visible and fill from there.
+        int count = (fillFrom - itemEnd) / (averageSize + spacing);
+        for (int i = 0; i < visibleItems.count(); ++i)
+            releaseItem(visibleItems.at(i));
+        visibleItems.clear();
+        modelIndex += count;
+        if (modelIndex >= model->count()) {
+            count -= modelIndex - model->count() + 1;
+            modelIndex = model->count() - 1;
+        } else if (modelIndex < 0) {
+            count -= modelIndex;
+            modelIndex = 0;
+        }
+        visibleIndex = modelIndex;
+        visiblePos = itemEnd + count * (averageSize + spacing) + 1;
+        itemEnd = visiblePos-1;
+    }
+
     bool changed = false;
     FxListItemSG *item = 0;
     qreal pos = itemEnd + 1;
@@ -1353,6 +1374,7 @@ void QSGListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
     } else {
         QSGFlickablePrivate::fixup(data, minExtent, maxExtent);
     }
+    data.inOvershoot = false;
     fixupMode = Normal;
 }
 
@@ -1425,10 +1447,10 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
                 data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
                 if (overShoot) {
                     if (data.flickTarget >= minExtent) {
-                        overshootDist = overShootDistance(v, vSize);
+                        overshootDist = overShootDistance(vSize);
                         data.flickTarget += overshootDist;
                     } else if (data.flickTarget <= maxExtent) {
-                        overshootDist = overShootDistance(v, vSize);
+                        overshootDist = overShootDistance(vSize);
                         data.flickTarget -= overshootDist;
                     }
                 }
@@ -1448,10 +1470,10 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
             } else if (overShoot) {
                 data.flickTarget = data.move.value() - dist;
                 if (data.flickTarget >= minExtent) {
-                    overshootDist = overShootDistance(v, vSize);
+                    overshootDist = overShootDistance(vSize);
                     data.flickTarget += overshootDist;
                 } else if (data.flickTarget <= maxExtent) {
-                    overshootDist = overShootDistance(v, vSize);
+                    overshootDist = overShootDistance(vSize);
                     data.flickTarget -= overshootDist;
                 }
             }
@@ -1831,9 +1853,11 @@ void QSGListView::setOrientation(QSGListView::Orientation orientation)
         if (d->orient == QSGListView::Vertical) {
             setContentWidth(-1);
             setFlickableDirection(VerticalFlick);
+            setContentX(0);
         } else {
             setContentHeight(-1);
             setFlickableDirection(HorizontalFlick);
+            setContentY(0);
         }
         d->regenerate();
         emit orientationChanged();
@@ -2131,7 +2155,7 @@ void QSGListView::viewportMoved()
         d->inFlickCorrection = true;
         // Near an end and it seems that the extent has changed?
         // Recalculate the flick so that we don't end up in an odd position.
-        if (yflick()) {
+        if (yflick() && !d->vData.inOvershoot) {
             if (d->vData.velocity > 0) {
                 const qreal minY = minYExtent();
                 if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2)
@@ -2147,7 +2171,7 @@ void QSGListView::viewportMoved()
             }
         }
 
-        if (xflick()) {
+        if (xflick() && !d->hData.inOvershoot) {
             if (d->hData.velocity > 0) {
                 const qreal minX = minXExtent();
                 if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2)
@@ -2311,7 +2335,7 @@ void QSGListView::keyPressEvent(QKeyEvent *event)
 {
     Q_D(QSGListView);
     if (d->model && d->model->count() && d->interactive) {
-        if ((!d->isRightToLeft() && event->key() == Qt::Key_Left)
+        if ((d->orient == QSGListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Left)
                     || (d->orient == QSGListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right)
                     || (d->orient == QSGListView::Vertical && event->key() == Qt::Key_Up)) {
             if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) {
@@ -2322,7 +2346,7 @@ void QSGListView::keyPressEvent(QKeyEvent *event)
                 event->accept();
                 return;
             }
-        } else if ((!d->isRightToLeft() && event->key() == Qt::Key_Right)
+        } else if ((d->orient == QSGListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Right)
                     || (d->orient == QSGListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Left)
                     || (d->orient == QSGListView::Vertical && event->key() == Qt::Key_Down)) {
             if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) {
index 1157a9a..887d78a 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: f0f6deb9a5e8bd078047dd090a3857290c8b4ea4
+// Commit: e1ffbc04131dc6f76fa76821c297d08162e4b1ee
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -179,6 +179,8 @@ QSGMouseAreaPrivate::QSGMouseAreaPrivate()
 : absorb(true), hovered(false), pressed(false), longPress(false),
   moved(false), stealMouse(false), doubleClick(false), preventStealing(false), drag(0)
 {
+    Q_Q(QSGMouseArea);
+    forwardTo = QDeclarativeListProperty<QSGItem>(q, forwardToList);
 }
 
 QSGMouseAreaPrivate::~QSGMouseAreaPrivate()
@@ -202,6 +204,18 @@ void QSGMouseAreaPrivate::saveEvent(QGraphicsSceneMouseEvent *event)
     lastModifiers = event->modifiers();
 }
 
+void QSGMouseAreaPrivate::forwardEvent(QGraphicsSceneMouseEvent* event)
+{
+    Q_Q(QSGMouseArea);
+    for(int i=0; i < forwardToList.count(); i++){
+        event->setPos(forwardToList[i]->mapFromScene(event->scenePos()));
+        forwardToList[i]->canvas()->sendEvent(forwardToList[i], event);
+        if(event->isAccepted())
+            break;
+    }
+    event->setPos(q->mapFromScene(event->scenePos()));
+}
+
 bool QSGMouseAreaPrivate::isPressAndHoldConnected() 
 {
     Q_Q(QSGMouseArea);
@@ -382,6 +396,9 @@ void QSGMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
         d->pressAndHoldTimer.start(PressAndHoldDelay, this);
         setKeepMouseGrab(d->stealMouse);
         event->setAccepted(setPressed(true));
+
+        if(!event->isAccepted() && d->forwardToList.count())
+           d->forwardEvent(event);
     }
 }
 
@@ -459,6 +476,9 @@ void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
     me.setX(d->lastPos.x());
     me.setY(d->lastPos.y());
     emit positionChanged(&me);
+
+    if(!event->isAccepted() && d->forwardToList.count())
+        d->forwardEvent(event);
 }
 
 void QSGMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
@@ -479,6 +499,9 @@ void QSGMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
         if (c && c->mouseGrabberItem() == this)
             ungrabMouse();
         setKeepMouseGrab(false);
+
+        if(!event->isAccepted() && d->forwardToList.count())
+            d->forwardEvent(event);
     }
     d->doubleClick = false;
 }
@@ -768,4 +791,10 @@ QSGDrag *QSGMouseArea::drag()
     return d->drag;
 }
 
+QDeclarativeListProperty<QSGItem> QSGMouseArea::forwardTo()
+{
+    Q_D(QSGMouseArea);
+    return d->forwardTo;
+}
+
 QT_END_NAMESPACE
index 24fb838..469b9f7 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 57676c237992e0aa5a93a4e8fa66b3e7b90c2c90
+// Commit: c6e6a35aeb8794d68a3ca0c4e27a3a1181c066b5
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -131,6 +131,7 @@ class Q_AUTOTEST_EXPORT QSGMouseArea : public QSGItem
     Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
     Q_PROPERTY(QSGDrag *drag READ drag CONSTANT) //### add flicking to QSGDrag or add a QDeclarativeFlick ???
     Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged)
+    Q_PROPERTY(QDeclarativeListProperty<QSGItem> forwardTo READ forwardTo);
 
 public:
     QSGMouseArea(QSGItem *parent=0);
@@ -158,6 +159,8 @@ public:
     bool preventStealing() const;
     void setPreventStealing(bool prevent);
 
+    QDeclarativeListProperty<QSGItem> forwardTo();
+
 Q_SIGNALS:
     void hoveredChanged();
     void pressedChanged();
index b4b64c6..e736c05 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 57676c237992e0aa5a93a4e8fa66b3e7b90c2c90
+// Commit: c6e6a35aeb8794d68a3ca0c4e27a3a1181c066b5
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -80,6 +80,7 @@ public:
     };
     void propagate(QSGMouseEvent* event, PropagateType);
     bool propagateHelper(QSGMouseEvent*, QSGItem*,const QPointF &, PropagateType);
+    void forwardEvent(QGraphicsSceneMouseEvent* event);
 
     bool isPressAndHoldConnected();
     bool isDoubleClickConnected();
@@ -105,6 +106,8 @@ public:
     Qt::MouseButtons lastButtons;
     Qt::KeyboardModifiers lastModifiers;
     QBasicTimer pressAndHoldTimer;
+    QDeclarativeListProperty<QSGItem> forwardTo;
+    QList<QSGItem*> forwardToList;
 };
 
 QT_END_NAMESPACE
index f7dda6c..87e550b 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: ac704e9f682378a5ec56e3f5c195dcf2f2dfa1ac
+// Commit: 8878e2c53a0c9408d4b468e2dad485743c32f58b
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -1213,6 +1213,8 @@ void QSGPathView::itemsRemoved(int modelIndex, int count)
     } else {
         d->regenerate();
         d->updateCurrent();
+        if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange)
+            d->snapToCurrent();
     }
     if (changedOffset)
         emit offsetChanged();
index e32f6bf..f21d873 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 2ec2dc55ddf424f5a7acd0a4729ddd9af2d7c398
+// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -121,7 +121,7 @@ void QSGPinchArea::touchEvent(QTouchEvent *event)
 void QSGPinchArea::updatePinch()
 {
     Q_D(QSGPinchArea);
-    if (d->touchPoints.count() != 2) {
+    if (d->touchPoints.count() == 0) {
         if (d->inPinch) {
             d->stealMouse = false;
             setKeepMouseGrab(false);
@@ -134,127 +134,141 @@ void QSGPinchArea::updatePinch()
             pe.setPreviousScale(d->pinchLastScale);
             pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
             pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-            pe.setPoint1(d->lastPoint1);
-            pe.setPoint2(d->lastPoint2);
+            pe.setPoint1(mapFromScene(d->lastPoint1));
+            pe.setPoint2(mapFromScene(d->lastPoint2));
             emit pinchFinished(&pe);
             d->pinchStartDist = 0;
+            d->pinchActivated = false;
             if (d->pinch && d->pinch->target())
                 d->pinch->setActive(false);
         }
         return;
     }
-    if (d->touchPoints.at(0).state() & Qt::TouchPointPressed
-        || d->touchPoints.at(1).state() & Qt::TouchPointPressed) {
-        d->sceneStartPoint1 = d->touchPoints.at(0).scenePos();
-        d->sceneStartPoint2 = d->touchPoints.at(1).scenePos();
+    QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
+    QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
+    if (d->touchPoints.count() == 2
+        && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) {
+        d->id1 = touchPoint1.id();
+        d->sceneStartPoint1 = touchPoint1.scenePos();
+        d->sceneStartPoint2 = touchPoint2.scenePos();
         d->inPinch = false;
         d->pinchRejected = false;
-    } else if (!d->pinchRejected){
-        QSGItem *grabber = canvas() ? canvas()->mouseGrabberItem() : 0;
-        if (grabber == this || !grabber || !grabber->keepMouseGrab()) {
-            const int dragThreshold = QApplication::startDragDistance();
-            QPointF p1 = d->touchPoints.at(0).scenePos();
-            QPointF p2 = d->touchPoints.at(1).scenePos();
-            qreal dx = p1.x() - p2.x();
-            qreal dy = p1.y() - p2.y();
-            qreal dist = sqrt(dx*dx + dy*dy);
-            QPointF sceneCenter = (p1 + p2)/2;
-            qreal angle = QLineF(p1, p2).angle();
-            if (angle > 180)
-                angle -= 360;
-            if (!d->inPinch) {
-                if (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
-                        || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
-                        || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
-                        || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold) {
-                    d->sceneStartCenter = sceneCenter;
-                    d->sceneLastCenter = sceneCenter;
-                    d->pinchStartCenter = mapFromScene(sceneCenter);
-                    d->pinchStartDist = dist;
-                    d->pinchStartAngle = angle;
-                    d->pinchLastScale = 1.0;
-                    d->pinchLastAngle = angle;
-                    d->pinchRotation = 0.0;
-                    d->lastPoint1 = d->touchPoints.at(0).pos();
-                    d->lastPoint2 = d->touchPoints.at(1).pos();
-                    QSGPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
-                    pe.setStartCenter(d->pinchStartCenter);
-                    pe.setPreviousCenter(d->pinchStartCenter);
-                    pe.setPreviousAngle(d->pinchLastAngle);
-                    pe.setPreviousScale(d->pinchLastScale);
-                    pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
-                    pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-                    pe.setPoint1(d->lastPoint1);
-                    pe.setPoint2(d->lastPoint2);
-                    emit pinchStarted(&pe);
-                    if (pe.accepted()) {
-                        d->inPinch = true;
-                        d->stealMouse = true;
-                        QSGCanvas *c = canvas();
-                        if (c && c->mouseGrabberItem() != this)
-                            grabMouse();
-                        setKeepMouseGrab(true);
-                        if (d->pinch && d->pinch->target()) {
-                            d->pinchStartPos = pinch()->target()->pos();
-                            d->pinchStartScale = d->pinch->target()->scale();
-                            d->pinchStartRotation = d->pinch->target()->rotation();
-                            d->pinch->setActive(true);
-                        }
-                    } else {
-                        d->pinchRejected = true;
-                    }
-                }
-            } else if (d->pinchStartDist > 0) {
-                qreal scale = dist / d->pinchStartDist;
-                qreal da = d->pinchLastAngle - angle;
-                if (da > 180)
-                    da -= 360;
-                else if (da < -180)
-                    da += 360;
-                d->pinchRotation += da;
-                QPointF pinchCenter = mapFromScene(sceneCenter);
-                QSGPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
+        d->pinchActivated = true;
+    } else if (d->pinchActivated && !d->pinchRejected){
+        const int dragThreshold = QApplication::startDragDistance();
+        QPointF p1 = touchPoint1.scenePos();
+        QPointF p2 = touchPoint2.scenePos();
+        qreal dx = p1.x() - p2.x();
+        qreal dy = p1.y() - p2.y();
+        qreal dist = sqrt(dx*dx + dy*dy);
+        QPointF sceneCenter = (p1 + p2)/2;
+        qreal angle = QLineF(p1, p2).angle();
+        if (d->touchPoints.count() == 1) {
+            // If we only have one point then just move the center
+            if (d->id1 == touchPoint1.id())
+                sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
+            else
+                sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
+            angle = d->pinchLastAngle;
+        }
+        d->id1 = touchPoint1.id();
+        if (angle > 180)
+            angle -= 360;
+        if (!d->inPinch) {
+            if (d->touchPoints.count() >= 2
+                    && (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
+                    || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
+                    || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
+                    || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold)) {
+                d->sceneStartCenter = sceneCenter;
+                d->sceneLastCenter = sceneCenter;
+                d->pinchStartCenter = mapFromScene(sceneCenter);
+                d->pinchStartDist = dist;
+                d->pinchStartAngle = angle;
+                d->pinchLastScale = 1.0;
+                d->pinchLastAngle = angle;
+                d->pinchRotation = 0.0;
+                d->lastPoint1 = p1;
+                d->lastPoint2 = p2;
+                QSGPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
                 pe.setStartCenter(d->pinchStartCenter);
-                pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
+                pe.setPreviousCenter(d->pinchStartCenter);
                 pe.setPreviousAngle(d->pinchLastAngle);
                 pe.setPreviousScale(d->pinchLastScale);
                 pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
                 pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-                pe.setPoint1(d->touchPoints.at(0).pos());
-                pe.setPoint2(d->touchPoints.at(1).pos());
-                d->pinchLastScale = scale;
-                d->sceneLastCenter = sceneCenter;
-                d->pinchLastAngle = angle;
-                d->lastPoint1 = d->touchPoints.at(0).pos();
-                d->lastPoint2 = d->touchPoints.at(1).pos();
-                emit pinchUpdated(&pe);
-                if (d->pinch && d->pinch->target()) {
-                    qreal s = d->pinchStartScale * scale;
-                    s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
-                    pinch()->target()->setScale(s);
-                    QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
-                    if (pinch()->axis() & QSGPinch::XAxis) {
-                        qreal x = pos.x();
-                        if (x < pinch()->xmin())
-                            x = pinch()->xmin();
-                        else if (x > pinch()->xmax())
-                            x = pinch()->xmax();
-                        pinch()->target()->setX(x);
-                    }
-                    if (pinch()->axis() & QSGPinch::YAxis) {
-                        qreal y = pos.y();
-                        if (y < pinch()->ymin())
-                            y = pinch()->ymin();
-                        else if (y > pinch()->ymax())
-                            y = pinch()->ymax();
-                        pinch()->target()->setY(y);
-                    }
-                    if (d->pinchStartRotation >= pinch()->minimumRotation()
-                            && d->pinchStartRotation <= pinch()->maximumRotation()) {
-                        qreal r = d->pinchRotation + d->pinchStartRotation;
-                        r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
-                        pinch()->target()->setRotation(r);
+                pe.setPoint1(mapFromScene(d->lastPoint1));
+                pe.setPoint2(mapFromScene(d->lastPoint2));
+                pe.setPointCount(d->touchPoints.count());
+                emit pinchStarted(&pe);
+                if (pe.accepted()) {
+                    d->inPinch = true;
+                    d->stealMouse = true;
+                    QSGCanvas *c = canvas();
+                    if (c && c->mouseGrabberItem() != this)
+                        grabMouse();
+                    setKeepMouseGrab(true);
+                    if (d->pinch && d->pinch->target()) {
+                        d->pinchStartPos = pinch()->target()->pos();
+                        d->pinchStartScale = d->pinch->target()->scale();
+                        d->pinchStartRotation = d->pinch->target()->rotation();
+                        d->pinch->setActive(true);
                     }
+                } else {
+                    d->pinchRejected = true;
+                }
+            }
+        } else if (d->pinchStartDist > 0) {
+            qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
+            qreal da = d->pinchLastAngle - angle;
+            if (da > 180)
+                da -= 360;
+            else if (da < -180)
+                da += 360;
+            d->pinchRotation += da;
+            QPointF pinchCenter = mapFromScene(sceneCenter);
+            QSGPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
+            pe.setStartCenter(d->pinchStartCenter);
+            pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
+            pe.setPreviousAngle(d->pinchLastAngle);
+            pe.setPreviousScale(d->pinchLastScale);
+            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+            pe.setPoint1(touchPoint1.pos());
+            pe.setPoint2(touchPoint2.pos());
+            pe.setPointCount(d->touchPoints.count());
+            d->pinchLastScale = scale;
+            d->sceneLastCenter = sceneCenter;
+            d->pinchLastAngle = angle;
+            d->lastPoint1 = touchPoint1.scenePos();
+            d->lastPoint2 = touchPoint2.scenePos();
+            emit pinchUpdated(&pe);
+            if (d->pinch && d->pinch->target()) {
+                qreal s = d->pinchStartScale * scale;
+                s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
+                pinch()->target()->setScale(s);
+                QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
+                if (pinch()->axis() & QSGPinch::XAxis) {
+                    qreal x = pos.x();
+                    if (x < pinch()->xmin())
+                        x = pinch()->xmin();
+                    else if (x > pinch()->xmax())
+                        x = pinch()->xmax();
+                    pinch()->target()->setX(x);
+                }
+                if (pinch()->axis() & QSGPinch::YAxis) {
+                    qreal y = pos.y();
+                    if (y < pinch()->ymin())
+                        y = pinch()->ymin();
+                    else if (y > pinch()->ymax())
+                        y = pinch()->ymax();
+                    pinch()->target()->setY(y);
+                }
+                if (d->pinchStartRotation >= pinch()->minimumRotation()
+                        && d->pinchStartRotation <= pinch()->maximumRotation()) {
+                    qreal r = d->pinchRotation + d->pinchStartRotation;
+                    r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
+                    pinch()->target()->setRotation(r);
                 }
             }
         }
index 04fd815..4cba636 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: ce59628ba366800fe2f3afdadc37be02f98480a7
+// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -204,11 +204,13 @@ class Q_AUTOTEST_EXPORT QSGPinchEvent : public QObject
     Q_PROPERTY(QPointF startPoint1 READ startPoint1)
     Q_PROPERTY(QPointF point2 READ point2)
     Q_PROPERTY(QPointF startPoint2 READ startPoint2)
+    Q_PROPERTY(int pointCount READ pointCount)
     Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
 
 public:
     QSGPinchEvent(QPointF c, qreal s, qreal a, qreal r)
-        : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r), m_accepted(true) {}
+        : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r)
+        , m_pointCount(0), m_accepted(true) {}
 
     QPointF center() const { return m_center; }
     QPointF startCenter() const { return m_startCenter; }
@@ -230,6 +232,8 @@ public:
     void setPoint2(QPointF p) { m_point2 = p; }
     QPointF startPoint2() const { return m_startPoint2; }
     void setStartPoint2(QPointF p) { m_startPoint2 = p; }
+    int pointCount() const { return m_pointCount; }
+    void setPointCount(int count) { m_pointCount = count; }
 
     bool accepted() const { return m_accepted; }
     void setAccepted(bool a) { m_accepted = a; }
@@ -247,6 +251,7 @@ private:
     QPointF m_point2;
     QPointF m_startPoint1;
     QPointF m_startPoint2;
+    int m_pointCount;
     bool m_accepted;
 };
 
index bdb3a51..b93d095 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 2ec2dc55ddf424f5a7acd0a4729ddd9af2d7c398
+// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -68,7 +68,8 @@ class QSGPinchAreaPrivate : public QSGItemPrivate
 public:
     QSGPinchAreaPrivate()
       : absorb(true), stealMouse(false), inPinch(false)
-      , pinchRejected(false), pinch(0), pinchStartDist(0), pinchStartScale(1.0)
+      , pinchRejected(false), pinchActivated(false)
+      , pinch(0), pinchStartDist(0), pinchStartScale(1.0)
       , pinchLastScale(1.0), pinchStartRotation(0.0), pinchStartAngle(0.0)
       , pinchLastAngle(0.0), pinchRotation(0.0)
     {
@@ -87,6 +88,7 @@ public:
     bool stealMouse : 1;
     bool inPinch : 1;
     bool pinchRejected : 1;
+    bool pinchActivated : 1;
     QSGPinch *pinch;
     QPointF sceneStartPoint1;
     QPointF sceneStartPoint2;
@@ -104,6 +106,7 @@ public:
     QPointF sceneLastCenter;
     QPointF pinchStartPos;
     QList<QTouchEvent::TouchPoint> touchPoints;
+    int id1;
 };
 
 QT_END_NAMESPACE
index f796006..f2ec7b2 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: a5c3c11e3e2204da6c8be9af98b38929366fafb8
+// Commit: cce89db1e2555cbca8fc28072e1c6dd737cec6c4
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -106,7 +106,7 @@ QSGTextPrivate::QSGTextPrivate()
   imageCacheDirty(true), updateOnComponentComplete(true),
   richText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false),
   requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false),
-  naturalWidth(0), doc(0), nodeType(NodeIsNull)
+  layoutTextElided(false), naturalWidth(0), doc(0), nodeType(NodeIsNull)
 {
     cacheAllTextAsImage = enableImageCache();
 }
@@ -219,6 +219,7 @@ void QSGTextPrivate::updateLayout()
         return;
     }
 
+    layoutTextElided = false;
     // Setup instance of QTextLayout for all cases other than richtext
     if (!richText) {
         layout.clearLayout();
@@ -229,10 +230,13 @@ void QSGTextPrivate::updateLayout()
             singleline = !tmp.contains(QChar::LineSeparator);
             if (singleline && !maximumLineCountValid && elideMode != QSGText::ElideNone && q->widthValid()) {
                 QFontMetrics fm(font);
-                tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width()); // XXX still worth layout...?
-                if (tmp != text && !truncated) {
-                    truncated = true;
-                    emit q->truncatedChanged();
+                tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
+                if (tmp != text) {
+                    layoutTextElided = true;
+                    if (!truncated) {
+                        truncated = true;
+                        emit q->truncatedChanged();
+                    }
                 }
             }
             layout.setText(tmp);
@@ -379,6 +383,12 @@ QRect QSGTextPrivate::setupTextLayout()
 
     if (requireImplicitWidth && q->widthValid()) {
         // requires an extra layout
+        QString elidedText;
+        if (layoutTextElided) {
+            // We have provided elided text to the layout, but we must calculate unelided width.
+            elidedText = layout.text();
+            layout.setText(text);
+        }
         layout.beginLayout();
         forever {
             QTextLine line = layout.createLine();
@@ -392,6 +402,8 @@ QRect QSGTextPrivate::setupTextLayout()
             br = br.united(line.naturalTextRect());
         }
         naturalWidth = br.width();
+        if (layoutTextElided)
+            layout.setText(elidedText);
     }
 
     if (maximumLineCountValid) {
index 7df91f8..8d26394 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: aeb330e3999ef3d7ae8d94b9330471f2a2a13554
+// Commit: 6e5a642c9484536fc173714f560f739944368cf5
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -119,6 +119,7 @@ public:
     bool truncated:1;
     bool hAlignImplicit:1;
     bool rightToLeftText:1;
+    bool layoutTextElided:1;
 
     QRect layedOutTextRect;
     QSize paintedSize;
index 57f9135..1c199ec 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 6980bca15b411f86b9fadb7484a6dd782b9d1403
+// Commit: ec40dd2bb51868bca10dbd0c9116f3224ff2b29b
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -318,6 +318,7 @@ void QSGTextEdit::setVAlign(QSGTextEdit::VAlignment alignment)
     d->vAlign = alignment;
     d->updateDefaultTextOption();
     updateSize();
+    moveCursorDelegate();
     emit verticalAlignmentChanged(d->vAlign);
 }
 
@@ -496,8 +497,6 @@ void QSGTextEdit::setCursorDelegate(QDeclarativeComponent* c)
     Q_D(QSGTextEdit);
     if(d->cursorComponent){
         if(d->cursor){
-            disconnect(d->control, SIGNAL(cursorPositionChanged()),
-                    this, SLOT(moveCursorDelegate()));
             d->control->setCursorWidth(-1);
             update(cursorRectangle());
             delete d->cursor;
@@ -523,8 +522,6 @@ void QSGTextEdit::loadCursorDelegate()
         return;
     d->cursor = qobject_cast<QSGItem*>(d->cursorComponent->create(qmlContext(this)));
     if(d->cursor){
-        connect(d->control, SIGNAL(cursorPositionChanged()),
-                this, SLOT(moveCursorDelegate()));
         d->control->setCursorWidth(0);
         update(cursorRectangle());
         QDeclarative_setParent_noEvent(d->cursor, this);
@@ -696,7 +693,7 @@ Qt::TextInteractionFlags QSGTextEdit::textInteractionFlags() const
 QRect QSGTextEdit::cursorRectangle() const
 {
     Q_D(const QSGTextEdit);
-    return d->control->cursorRect().toRect().translated(0,-d->yoff);
+    return d->control->cursorRect().toRect().translated(0,d->yoff);
 }
 
 bool QSGTextEdit::event(QEvent *event)
@@ -985,7 +982,7 @@ void QSGTextEditPrivate::init()
     QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
-    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorRectangleChanged()));
+    QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(moveCursorDelegate()));
     QObject::connect(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
 #ifndef QT_NO_CLIPBOARD
     QObject::connect(q, SIGNAL(readOnlyChanged(bool)), q, SLOT(q_canPasteChanged()));
@@ -1010,16 +1007,17 @@ void QSGTextEdit::q_textChanged()
     d->updateDefaultTextOption();
     updateSize();
     updateTotalLines();
-    updateMicroFocus();
     emit textChanged(d->text);
 }
 
 void QSGTextEdit::moveCursorDelegate()
 {
     Q_D(QSGTextEdit);
+    updateMicroFocus();
+    emit cursorRectangleChanged();
     if(!d->cursor)
         return;
-    QRectF cursorRect = d->control->cursorRect();
+    QRectF cursorRect = cursorRectangle();
     d->cursor->setX(cursorRect.x());
     d->cursor->setY(cursorRect.y());
 }
@@ -1052,7 +1050,6 @@ void QSGTextEdit::updateSelectionMarkers()
         d->lastSelectionEnd = d->control->textCursor().selectionEnd();
         emit selectionEndChanged();
     }
-    updateMicroFocus();
 }
 
 QRectF QSGTextEdit::boundingRect() const
index 9631b3b..4eab28b 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: b94176e69efc3948696c6774d5a228fc753b5b29
+// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -442,6 +442,20 @@ bool QSGTextInput::hasAcceptableInput() const
     return d->control->hasAcceptableInput();
 }
 
+void QSGTextInputPrivate::updateInputMethodHints()
+{
+    Q_Q(QSGTextInput);
+    Qt::InputMethodHints hints = inputMethodHints;
+    uint echo = control->echoMode();
+    if (echo == QSGTextInput::Password || echo == QSGTextInput::NoEcho)
+        hints |= Qt::ImhHiddenText;
+    else if (echo == QSGTextInput::PasswordEchoOnEdit)
+        hints &= ~Qt::ImhHiddenText;
+    if (echo != QSGTextInput::Normal)
+        hints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+    q->setInputMethodHints(hints);
+}
+
 QSGTextInput::EchoMode QSGTextInput::echoMode() const
 {
     Q_D(const QSGTextInput);
@@ -453,21 +467,27 @@ void QSGTextInput::setEchoMode(QSGTextInput::EchoMode echo)
     Q_D(QSGTextInput);
     if (echoMode() == echo)
         return;
-    Qt::InputMethodHints imHints = inputMethodHints();
-    if (echo == Password || echo == NoEcho)
-        imHints |= Qt::ImhHiddenText;
-    else
-        imHints &= ~Qt::ImhHiddenText;
-    if (echo != Normal)
-        imHints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    else
-        imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    setInputMethodHints(imHints);
     d->control->setEchoMode((uint)echo);
+    d->updateInputMethodHints();
     q_textChanged();
     emit echoModeChanged(echoMode());
 }
 
+Qt::InputMethodHints QSGTextInput::imHints() const
+{
+    Q_D(const QSGTextInput);
+    return d->inputMethodHints;
+}
+
+void QSGTextInput::setIMHints(Qt::InputMethodHints hints)
+{
+    Q_D(QSGTextInput);
+    if (d->inputMethodHints == hints)
+        return;
+    d->inputMethodHints = hints;
+    d->updateInputMethodHints();
+}
+
 QDeclarativeComponent* QSGTextInput::cursorDelegate() const
 {
     Q_D(const QSGTextInput);
@@ -485,6 +505,8 @@ void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c)
         //note that the components are owned by something else
         disconnect(d->control, SIGNAL(cursorPositionChanged(int,int)),
                 this, SLOT(moveCursor()));
+        disconnect(d->control, SIGNAL(updateMicroFocus()),
+                this, SLOT(moveCursor()));
         delete d->cursorItem;
     }else{
         d->startCreatingCursor();
@@ -497,7 +519,9 @@ void QSGTextInputPrivate::startCreatingCursor()
 {
     Q_Q(QSGTextInput);
     q->connect(control, SIGNAL(cursorPositionChanged(int,int)),
-            q, SLOT(moveCursor()));
+            q, SLOT(moveCursor()), Qt::UniqueConnection);
+    q->connect(control, SIGNAL(updateMicroFocus()),
+            q, SLOT(moveCursor()), Qt::UniqueConnection);
     if(cursorComponent->isReady()){
         q->createCursor();
     }else if(cursorComponent->isLoading()){
@@ -648,9 +672,10 @@ void QSGTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
     }
     if (d->selectByMouse) {
         setKeepMouseGrab(false);
+        d->selectPressed = true;
         d->pressPos = event->pos();
     }
-    bool mark = event->modifiers() & Qt::ShiftModifier;
+    bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse;
     int cursor = d->xToPos(event->pos().x());
     d->control->moveCursor(cursor, mark);
     event->setAccepted(true);
@@ -661,7 +686,7 @@ void QSGTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
     Q_D(QSGTextInput);
     if (d->sendMouseEventToInputContext(event, QEvent::MouseMove))
         return;
-    if (d->selectByMouse) {
+    if (d->selectPressed) {
         if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance())
             setKeepMouseGrab(true);
         moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode);
@@ -676,8 +701,10 @@ void QSGTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
     Q_D(QSGTextInput);
     if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonRelease))
         return;
-    if (d->selectByMouse)
+    if (d->selectPressed) {
+        d->selectPressed = false;
         setKeepMouseGrab(false);
+    }
     if (!d->showInputPanelOnFocus) { // input panel on click
         if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) {
             if (canvas() && canvas() == qApp->focusWidget()) {
@@ -731,6 +758,8 @@ bool QSGTextInputPrivate::sendMouseEventToInputContext(
 
 void QSGTextInput::mouseUngrabEvent()
 {
+    Q_D(QSGTextInput);
+    d->selectPressed = false;
     setKeepMouseGrab(false);
 }
 
index ee04579..ccea485 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 27e4302b7f45f22180693d26747f419177c81e27
+// Commit: 2f173e4945dd8414636c1061acfaf9c2d8b718d8
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -83,7 +83,7 @@ class Q_AUTOTEST_EXPORT QSGTextInput : public QSGImplicitSizePaintedItem
     Q_PROPERTY(QValidator* validator READ validator WRITE setValidator NOTIFY validatorChanged)
 #endif
     Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask NOTIFY inputMaskChanged)
-    Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints)
+    Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ imHints WRITE setIMHints)
 
     Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged)
     Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged)
@@ -212,6 +212,9 @@ public:
 
     bool isInputMethodComposing() const;
 
+    Qt::InputMethodHints imHints() const;
+    void setIMHints(Qt::InputMethodHints hints);
+
 Q_SIGNALS:
     void textChanged();
     void cursorPositionChanged();
index 00db1e9..22c95a7 100644 (file)
@@ -1,4 +1,4 @@
-// Commit: 27e4302b7f45f22180693d26747f419177c81e27
+// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0
 /****************************************************************************
 **
 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -72,10 +72,11 @@ public:
     QSGTextInputPrivate() : control(new QLineControl(QString())),
                  color((QRgb)0), style(QSGText::Normal),
                  styleColor((QRgb)0), hAlign(QSGTextInput::AlignLeft),
-                 mouseSelectionMode(QSGTextInput::SelectCharacters),
+                 mouseSelectionMode(QSGTextInput::SelectCharacters), inputMethodHints(Qt::ImhNone),
                  hscroll(0), oldScroll(0), oldValidity(false), focused(false), focusOnPress(true),
                  showInputPanelOnFocus(true), clickCausedFocus(false), cursorVisible(false),
-                 autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true)
+                 autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true),
+                 selectPressed(false)
     {
 #ifdef Q_OS_SYMBIAN
         if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) {
@@ -106,6 +107,7 @@ public:
     void mirrorChange();
     int calculateTextWidth();
     bool sendMouseEventToInputContext(QGraphicsSceneMouseEvent *event, QEvent::Type eventType);
+    void updateInputMethodHints();
 
     QLineControl* control;
 
@@ -118,6 +120,7 @@ public:
     QColor  styleColor;
     QSGTextInput::HAlignment hAlign;
     QSGTextInput::SelectionMode mouseSelectionMode;
+    Qt::InputMethodHints inputMethodHints;
     QPointer<QDeclarativeComponent> cursorComponent;
     QPointer<QSGItem> cursorItem;
     QPointF pressPos;
@@ -139,6 +142,7 @@ public:
     bool selectByMouse:1;
     bool canPaste:1;
     bool hAlignImplicit:1;
+    bool selectPressed:1;
 
     static inline QSGTextInputPrivate *get(QSGTextInput *t) {
         return t->d_func();
index 1532281..2cc6b3e 100644 (file)
@@ -106,7 +106,7 @@ void tst_qsgflickable::create()
     QCOMPARE(obj->isInteractive(), true);
     QCOMPARE(obj->boundsBehavior(), QSGFlickable::DragAndOvershootBounds);
     QCOMPARE(obj->pressDelay(), 0);
-    QCOMPARE(obj->maximumFlickVelocity(), 2000.);
+    QCOMPARE(obj->maximumFlickVelocity(), 2500.);
 
     delete obj;
 }