From d87e2627cbc3f818e23c9c80b03cc665e5f3d444 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Thu, 3 Feb 2011 14:59:56 +1000 Subject: Don't accept input methods when a TextEdit or TextInput is read only. Neither would open a software input panel or allow text entry while read only, but on Symbian at least the text input mode indicator was still displayed giving the appearance of being able to enter text. Task-number: QT-4497 Reviewed-by: Damian Jansen --- src/declarative/graphicsitems/qdeclarativetextedit.cpp | 1 + src/declarative/graphicsitems/qdeclarativetextinput.cpp | 1 + .../qdeclarativetextedit/tst_qdeclarativetextedit.cpp | 10 ++++++++++ .../qdeclarativetextinput/tst_qdeclarativetextinput.cpp | 10 ++++++++++ 4 files changed, 22 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index f63e4cb..17354eb 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -1023,6 +1023,7 @@ void QDeclarativeTextEdit::setReadOnly(bool r) if (r == isReadOnly()) return; + setFlag(QGraphicsItem::ItemAcceptsInputMethod, !r); Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse; if (r) { diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 012d408..57e60ac 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -377,6 +377,7 @@ void QDeclarativeTextInput::setReadOnly(bool ro) if (d->control->isReadOnly() == ro) return; + setFlag(QGraphicsItem::ItemAcceptsInputMethod, !ro); d->control->setReadOnly(ro); emit readOnlyChanged(ro); diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index b82aca8..7d5101c 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -1676,6 +1676,16 @@ void tst_qdeclarativetextedit::openInputPanelOnFocus() QApplication::processEvents(); QVERIFY(view.inputContext() == 0); QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + + // input method should not be enabled + // if TextEdit is read only. + edit.setReadOnly(true); + ic.openInputPanelReceived = false; + edit.setFocus(true); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, false); + QVERIFY(view.inputContext() == 0); + QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); } void tst_qdeclarativetextedit::geometrySignals() diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 675367c..42a0659 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -1605,6 +1605,16 @@ void tst_qdeclarativetextinput::openInputPanelOnFocus() QApplication::processEvents(); QVERIFY(view.inputContext() == 0); QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + + // input method should not be enabled + // if TextEdit is read only. + input.setReadOnly(true); + ic.openInputPanelReceived = false; + input.setFocus(true); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, false); + QVERIFY(view.inputContext() == 0); + QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); } class MyTextInput : public QDeclarativeTextInput -- cgit v0.12 From 9f8a181a619649c8a227e92f3d16677f4b7cb30a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 4 Feb 2011 14:11:09 +1000 Subject: Clarify case preservation in QDeclarativeImageProviders Task-number: QTBUG-15905 Reviewed-by: Martin Jones --- src/declarative/qml/qdeclarativeengine.cpp | 2 +- src/declarative/qml/qdeclarativeimageprovider.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 890f500..37df226 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -776,7 +776,7 @@ void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativ { Q_D(QDeclarativeEngine); QMutexLocker locker(&d->mutex); - d->imageProviders.insert(providerId, QSharedPointer(provider)); + d->imageProviders.insert(providerId.toLower(), QSharedPointer(provider)); } /*! diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index 560077f..f111c20 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -75,6 +75,16 @@ public: invokes the appropriate image provider according to the providers that have been registered through QDeclarativeEngine::addImageProvider(). + Note that the identifiers are case-insensitive, but the rest of the URL will be passed on with + preserved case. For example, the below snippet would still specify that the image is loaded by the + image provider named "myimageprovider", but it would request a different image than the above snippet + ("Image.png" instead of "image.png"). + \qml + Image { source: "image://MyImageProvider/Image.png" } + \endqml + + If you want the rest of the URL to be case insensitive, you will have to take care + of that yourself inside your image provider. \section2 An example -- cgit v0.12 From 80d0fe9cbd92288a08d5ced8767f1edb651dae37 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 3 Feb 2011 16:54:13 +1000 Subject: AnimatedImage does not notify on status change. Task-number: QTBUG-16520 Reviewed-by: Michael Brasser --- .../graphicsitems/qdeclarativeanimatedimage.cpp | 22 +++++++++++++++++--- .../graphicsitems/qdeclarativeanimatedimage_p.h | 1 + .../qdeclarativeanimatedimage/data/qtbug-16520.qml | 17 +++++++++++++++ .../tst_qdeclarativeanimatedimage.cpp | 24 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeanimatedimage/data/qtbug-16520.qml diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp index 27bb6a2..016b87d 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp @@ -221,13 +221,22 @@ void QDeclarativeAnimatedImage::setSource(const QUrl &url) } d->url = url; + emit sourceChanged(d->url); - if (url.isEmpty()) { + if (isComponentComplete()) + load(); +} + +void QDeclarativeAnimatedImage::load() +{ + Q_D(QDeclarativeAnimatedImage); + + if (d->url.isEmpty()) { delete d->_movie; d->status = Null; } else { #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML - QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url); + QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url); if (!lf.isEmpty()) { //### should be unified with movieRequestFinished d->_movie = new QMovie(lf); @@ -235,6 +244,8 @@ void QDeclarativeAnimatedImage::setSource(const QUrl &url) qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString(); delete d->_movie; d->_movie = 0; + d->status = Error; + emit statusChanged(d->status); return; } connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)), @@ -264,7 +275,6 @@ void QDeclarativeAnimatedImage::setSource(const QUrl &url) QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(movieRequestFinished())); } - emit statusChanged(d->status); } @@ -294,6 +304,8 @@ void QDeclarativeAnimatedImage::movieRequestFinished() #endif delete d->_movie; d->_movie = 0; + d->status = Error; + emit statusChanged(d->status); return; } connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)), @@ -310,6 +322,8 @@ void QDeclarativeAnimatedImage::movieRequestFinished() if(d->paused) d->_movie->setPaused(true); d->setPixmap(d->_movie->currentPixmap()); + d->status = Ready; + emit statusChanged(d->status); } void QDeclarativeAnimatedImage::movieUpdate() @@ -336,6 +350,8 @@ void QDeclarativeAnimatedImage::componentComplete() { Q_D(QDeclarativeAnimatedImage); QDeclarativeItem::componentComplete(); // NOT QDeclarativeImage + if (d->url.isValid()) + load(); if (!d->reply) { setCurrentFrame(d->preset_currentframe); d->preset_currentframe = 0; diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p.h b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p.h index e5025bf..e2ed70b 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p.h @@ -97,6 +97,7 @@ private Q_SLOTS: void playingStatusChanged(); protected: + virtual void load(); void componentComplete(); private: diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/data/qtbug-16520.qml b/tests/auto/declarative/qdeclarativeanimatedimage/data/qtbug-16520.qml new file mode 100644 index 0000000..cf5b601 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanimatedimage/data/qtbug-16520.qml @@ -0,0 +1,17 @@ +import QtQuick 1.0 + +Rectangle { + width: 500 + height: 500 + + AnimatedImage { + objectName: "anim" + anchors.centerIn: parent + asynchronous: true + opacity: status == AnimatedImage.Ready ? 1 : 0 + + Behavior on opacity { + NumberAnimation { duration: 1000 } + } + } +} diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp b/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp index eba4239..104ee15 100644 --- a/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp +++ b/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp @@ -75,6 +75,7 @@ private slots: void sourceSize(); void sourceSizeReadOnly(); void invalidSource(); + void qtbug_16520(); private: QPixmap grabScene(QGraphicsScene *scene, int width, int height); @@ -307,6 +308,29 @@ void tst_qdeclarativeanimatedimage::invalidSource() QVERIFY(!anim->isPaused()); QCOMPARE(anim->currentFrame(), 0); QCOMPARE(anim->frameCount(), 0); + QTRY_VERIFY(anim->status() == 3); +} + +void tst_qdeclarativeanimatedimage::qtbug_16520() +{ + TestHTTPServer server(14449); + QVERIFY(server.isValid()); + server.serveDirectory(SRCDIR "/data"); + + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/qtbug-16520.qml")); + QTRY_VERIFY(component.isReady()); + + QDeclarativeRectangle *root = qobject_cast(component.create()); + QVERIFY(root); + QDeclarativeAnimatedImage *anim = root->findChild("anim"); + + anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif"); + + QTRY_VERIFY(anim->opacity() == 0); + QTRY_VERIFY(anim->opacity() == 1); + + delete anim; } QTEST_MAIN(tst_qdeclarativeanimatedimage) -- cgit v0.12 From a9f1eaa6a368bf7a72b52c428728a3e3e0a76209 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Fri, 4 Feb 2011 10:36:38 +1000 Subject: modelChanged() should not be emitted until view is repopulated Otherwise, itemAt() returns invalid values at the time that modelChanged() is emitted. Task-number: QTBUG-17156 Reviewed-by: Martin Jones --- .../graphicsitems/qdeclarativerepeater.cpp | 2 +- .../qdeclarativerepeater/data/modelChanged.qml | 26 +++++++++++++++++ .../tst_qdeclarativerepeater.cpp | 33 ++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativerepeater/data/modelChanged.qml diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index 8455513..4d0f34c 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -198,7 +198,6 @@ void QDeclarativeRepeater::setModel(const QVariant &model) */ } d->dataSource = model; - emit modelChanged(); QObject *object = qvariant_cast(model); QDeclarativeVisualModel *vim = 0; if (object && (vim = qobject_cast(object))) { @@ -226,6 +225,7 @@ void QDeclarativeRepeater::setModel(const QVariant &model) */ regenerate(); } + emit modelChanged(); emit countChanged(); } diff --git a/tests/auto/declarative/qdeclarativerepeater/data/modelChanged.qml b/tests/auto/declarative/qdeclarativerepeater/data/modelChanged.qml new file mode 100644 index 0000000..0b57d50 --- /dev/null +++ b/tests/auto/declarative/qdeclarativerepeater/data/modelChanged.qml @@ -0,0 +1,26 @@ +import QtQuick 1.1 + +Column { + Repeater { + id: repeater + objectName: "repeater" + + property int itemsCount + property variant itemsFound: [] + + delegate: Rectangle { + color: "red" + width: (index+1)*50 + height: 50 + } + + onModelChanged: { + repeater.itemsCount = repeater.count + var items = [] + for (var i=0; icount(), dataA.count()); + for (int i=0; icount(); i++) + QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object + QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged())); QSignalSpy countSpy(repeater, SIGNAL(countChanged())); QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QDeclarativeItem*))); QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QDeclarativeItem*))); @@ -547,6 +551,7 @@ void tst_QDeclarativeRepeater::resetModel() ctxt->setContextProperty("testData", dataB); QCOMPARE(repeater->count(), dataB.count()); + QCOMPARE(modelChangedSpy.count(), 1); QCOMPARE(countSpy.count(), 1); QCOMPARE(removedSpy.count(), dataA.count()); QCOMPARE(addedSpy.count(), dataB.count()); @@ -554,6 +559,7 @@ void tst_QDeclarativeRepeater::resetModel() QCOMPARE(addedSpy.at(i).at(0).toInt(), i); QCOMPARE(addedSpy.at(i).at(1).value(), repeater->itemAt(i)); } + modelChangedSpy.clear(); countSpy.clear(); removedSpy.clear(); addedSpy.clear(); @@ -562,6 +568,7 @@ void tst_QDeclarativeRepeater::resetModel() repeater->setModel(dataA); QCOMPARE(repeater->count(), dataA.count()); + QCOMPARE(modelChangedSpy.count(), 1); QCOMPARE(countSpy.count(), 1); QCOMPARE(removedSpy.count(), dataB.count()); QCOMPARE(addedSpy.count(), dataA.count()); @@ -569,6 +576,32 @@ void tst_QDeclarativeRepeater::resetModel() QCOMPARE(addedSpy.at(i).at(0).toInt(), i); QCOMPARE(addedSpy.at(i).at(1).value(), repeater->itemAt(i)); } + + delete canvas; +} + +// QTBUG-17156 +void tst_QDeclarativeRepeater::modelChanged() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, TEST_FILE("/modelChanged.qml")); + + QDeclarativeItem *rootObject = qobject_cast(component.create()); + QVERIFY(rootObject); + QDeclarativeRepeater *repeater = findItem(rootObject, "repeater"); + QVERIFY(repeater); + + repeater->setModel(4); + QCOMPARE(repeater->count(), 4); + QCOMPARE(repeater->property("itemsCount"), 4); + QCOMPARE(repeater->property("itemsFound").toList().count(), 4); + + repeater->setModel(10); + QCOMPARE(repeater->count(), 10); + QCOMPARE(repeater->property("itemsCount"), 10); + QCOMPARE(repeater->property("itemsFound").toList().count(), 10); + + delete rootObject; } void tst_QDeclarativeRepeater::properties() -- cgit v0.12