summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/util/qmllistmodel.cpp73
-rw-r--r--src/declarative/util/qmllistmodel_p.h3
-rw-r--r--tests/auto/declarative/qmlgraphicswebview/data/javaScript.qml5
-rw-r--r--tests/auto/declarative/qmllistmodel/qmllistmodel.pro6
-rw-r--r--tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp138
-rw-r--r--tests/auto/declarative/visual/webview/embedding/egg.qml27
-rw-r--r--tests/auto/declarative/visual/webview/embedding/nesting.html9
-rw-r--r--tests/auto/declarative/visual/webview/embedding/nesting.qml8
8 files changed, 253 insertions, 16 deletions
diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp
index afc6735..fbd957c 100644
--- a/src/declarative/util/qmllistmodel.cpp
+++ b/src/declarative/util/qmllistmodel.cpp
@@ -45,9 +45,11 @@
#include <private/qmlcustomparser_p.h>
#include <private/qmlparser_p.h>
#include "qmlopenmetaobject_p.h"
+#include <private/qmlengine_p.h>
#include <qmlcontext.h>
#include "qmllistmodel_p.h"
#include <QtScript/qscriptvalueiterator.h>
+#include "qmlinfo.h"
Q_DECLARE_METATYPE(QListModelInterface *)
@@ -264,6 +266,7 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(ModelNode *)
QT_BEGIN_NAMESPACE
+
void ModelNode::setObjectValue(const QScriptValue& valuemap) {
QScriptValueIterator it(valuemap);
while (it.hasNext()) {
@@ -451,14 +454,17 @@ void QmlListModel::clear()
*/
void QmlListModel::remove(int index)
{
- if (_root) {
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- _root->values.removeAt(index);
- if (node)
- delete node;
- emit itemsRemoved(index,1);
- emit countChanged(_root->values.count());
+ if (!_root || index < 0 || index >= _root->values.count()) {
+ qmlInfo(tr("remove: index %1 out of range").arg(index),this);
+ return;
}
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ _root->values.removeAt(index);
+ if (node)
+ delete node;
+ emit itemsRemoved(index,1);
+ emit countChanged(_root->values.count());
}
/*!
@@ -480,9 +486,11 @@ void QmlListModel::insert(int index, const QScriptValue& valuemap)
{
if (!_root)
_root = new ModelNode;
- if (index >= _root->values.count()) {
+ if (index >= _root->values.count() || index<0) {
if (index == _root->values.count())
append(valuemap);
+ else
+ qmlInfo(tr("insert: index %1 out of range").arg(index),this);
return;
}
ModelNode *mn = new ModelNode;
@@ -508,8 +516,10 @@ void QmlListModel::insert(int index, const QScriptValue& valuemap)
*/
void QmlListModel::move(int from, int to, int n)
{
- if (from+n > count() || to+n > count() || n==0 || from==to || from < 0 || to < 0)
+ if (n==0 || from==to)
return;
+ if (from+n > count() || to+n > count() || from < 0 || to < 0)
+ qmlInfo(tr("move: out of range"),this);
int origfrom=from; // preserve actual move, so any animations are correct
int origto=to;
int orign=n;
@@ -556,7 +566,7 @@ void QmlListModel::move(int from, int to, int n)
void QmlListModel::append(const QScriptValue& valuemap)
{
if (!valuemap.isObject()) {
- qWarning("ListModel::append: value is not an object");
+ qmlInfo(tr("append: value is not an object"),this);
return;
}
if (!_root)
@@ -569,10 +579,43 @@ void QmlListModel::append(const QScriptValue& valuemap)
}
/*!
+ \qmlmethod dict ListModel::get(index)
+
+ Returns the item at \a index in the list model.
+
+ \code
+ FruitModel.append({"cost": 5.95, "name":"Pizza"})
+ FruitModel.get(0).cost
+ \endcode
+
+ The \a index must be an element in the list.
+
+ \sa append()
+*/
+QScriptValue QmlListModel::get(int index) const
+{
+ if (index >= count()) {
+ qmlInfo(tr("get: index %1 out of range").arg(index),this);
+ return 0;
+ }
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ if (!node)
+ return 0;
+ QmlEngine *eng = qmlEngine(this);
+ if (!eng) {
+ qWarning("Cannot call QmlListModel::get() without a QmlEngine");
+ return 0;
+ }
+ return QmlEnginePrivate::qmlScriptObject(node->object(), eng);
+}
+
+/*!
\qmlmethod ListModel::set(index,dict)
- Changes the item at \a index in the list model to the
- values in \a dict.
+ Changes the item at \a index in the list model with the
+ values in \a dict. Properties not appearing in \a valuemap
+ are left unchanged.
\code
FruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
@@ -586,8 +629,8 @@ void QmlListModel::set(int index, const QScriptValue& valuemap)
{
if (!_root)
_root = new ModelNode;
- if ( index >= _root->values.count()) {
- qWarning() << "ListModel::set index out of range:" << index;
+ if ( index > _root->values.count()) {
+ qmlInfo(tr("set: index %1 out of range").arg(index),this);
return;
}
if (index == _root->values.count())
@@ -628,7 +671,7 @@ void QmlListModel::set(int index, const QString& property, const QVariant& value
if (!_root)
_root = new ModelNode;
if ( index >= _root->values.count()) {
- qWarning() << "ListModel::set index out of range:" << index;
+ qmlInfo(tr("set: index %1 out of range").arg(index),this);
return;
}
ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
diff --git a/src/declarative/util/qmllistmodel_p.h b/src/declarative/util/qmllistmodel_p.h
index 31365d1..34b1562 100644
--- a/src/declarative/util/qmllistmodel_p.h
+++ b/src/declarative/util/qmllistmodel_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
struct ModelNode;
-class QmlListModel : public QListModelInterface
+class Q_DECLARATIVE_EXPORT QmlListModel : public QListModelInterface
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
@@ -77,6 +77,7 @@ public:
Q_INVOKABLE void remove(int index);
Q_INVOKABLE void append(const QScriptValue&);
Q_INVOKABLE void insert(int index, const QScriptValue&);
+ Q_INVOKABLE QScriptValue get(int index) const;
Q_INVOKABLE void set(int index, const QScriptValue&);
Q_INVOKABLE void set(int index, const QString& property, const QVariant& value);
Q_INVOKABLE void move(int from, int to, int count);
diff --git a/tests/auto/declarative/qmlgraphicswebview/data/javaScript.qml b/tests/auto/declarative/qmlgraphicswebview/data/javaScript.qml
new file mode 100644
index 0000000..75d0cea
--- /dev/null
+++ b/tests/auto/declarative/qmlgraphicswebview/data/javaScript.qml
@@ -0,0 +1,5 @@
+import Qt 4.6
+
+WebView {
+ url: "javaScript.html"
+}
diff --git a/tests/auto/declarative/qmllistmodel/qmllistmodel.pro b/tests/auto/declarative/qmllistmodel/qmllistmodel.pro
new file mode 100644
index 0000000..60b0c4b
--- /dev/null
+++ b/tests/auto/declarative/qmllistmodel/qmllistmodel.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative
+QT += script
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qmllistmodel.cpp
diff --git a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
new file mode 100644
index 0000000..9ce1a7c
--- /dev/null
+++ b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtDeclarative/private/qmllistmodel_p.h>
+#include <QtDeclarative/private/qmlexpression_p.h>
+#include <QDebug>
+
+class tst_QmlListModel : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QmlListModel() {}
+
+private slots:
+ void dynamic_data();
+ void dynamic();
+};
+
+void tst_QmlListModel::dynamic_data()
+{
+ QTest::addColumn<QString>("script");
+ QTest::addColumn<int>("result");
+ QTest::addColumn<QString>("warning");
+
+ // Simple flat model
+
+ QTest::newRow("count") << "count" << 0 << "";
+
+ QTest::newRow("append1") << "{append({'foo':123});count}" << 1 << "";
+ QTest::newRow("append2") << "{append({'foo':123,'bar':456});count}" << 1 << "";
+ QTest::newRow("append3a") << "{append({'foo':123});append({'foo':456});get(0).foo}" << 123 << "";
+ QTest::newRow("append3b") << "{append({'foo':123});append({'foo':456});get(1).foo}" << 456 << "";
+
+ QTest::newRow("clear1") << "{append({'foo':456});clear();count}" << 0 << "";
+ QTest::newRow("clear2") << "{append({'foo':123});append({'foo':456});clear();count}" << 0 << "";
+ QTest::newRow("clear2") << "{append({'foo':123});clear();get(0).foo}" << 0 << "QML QmlListModel (unknown location) get: index 0 out of range";
+
+ QTest::newRow("remove1") << "{append({'foo':123});remove(0);count}" << 0 << "";
+ QTest::newRow("remove2a") << "{append({'foo':123});append({'foo':456});remove(0);count}" << 1 << "";
+ QTest::newRow("remove2b") << "{append({'foo':123});append({'foo':456});remove(0);get(0).foo}" << 456 << "";
+ QTest::newRow("remove2c") << "{append({'foo':123});append({'foo':456});remove(1);get(0).foo}" << 123 << "";
+ QTest::newRow("remove3") << "{append({'foo':123});remove(0);get(0).foo}" << 0 << "QML QmlListModel (unknown location) get: index 0 out of range";
+
+ QTest::newRow("insert1") << "{insert(0,{'foo':123});count}" << 1 << "";
+ QTest::newRow("insert2") << "{insert(1,{'foo':123});count}" << 0 << "QML QmlListModel (unknown location) insert: index 1 out of range";
+ QTest::newRow("insert3a") << "{append({'foo':123});insert(1,{'foo':456});count}" << 2 << "";
+ QTest::newRow("insert3b") << "{append({'foo':123});insert(1,{'foo':456});get(0).foo}" << 123 << "";
+ QTest::newRow("insert3c") << "{append({'foo':123});insert(1,{'foo':456});get(1).foo}" << 456 << "";
+ QTest::newRow("insert3d") << "{append({'foo':123});insert(0,{'foo':456});get(0).foo}" << 456 << "";
+ QTest::newRow("insert3e") << "{append({'foo':123});insert(0,{'foo':456});get(1).foo}" << 123 << "";
+ QTest::newRow("insert4") << "{append({'foo':123});insert(-1,{'foo':456})}" << 0 << "QML QmlListModel (unknown location) insert: index -1 out of range";
+
+ QTest::newRow("set1") << "{append({'foo':123});set(0,{'foo':456});count}" << 1 << "";
+ QTest::newRow("set2") << "{append({'foo':123});set(0,{'foo':456});get(0).foo}" << 456 << "";
+ QTest::newRow("set3a") << "{append({'foo':123,'bar':456});set(0,{'foo':999});get(0).foo}" << 999 << "";
+ QTest::newRow("set3b") << "{append({'foo':123,'bar':456});set(0,{'foo':999});get(0).bar}" << 456 << "";
+
+ QTest::newRow("setprop1") << "{append({'foo':123});set(0,'foo',456);count}" << 1 << "";
+ QTest::newRow("setprop2") << "{append({'foo':123});set(0,'foo',456);get(0).foo}" << 456 << "";
+ QTest::newRow("setprop3a") << "{append({'foo':123,'bar':456});set(0,'foo',999);get(0).foo}" << 999 << "";
+ QTest::newRow("setprop3b") << "{append({'foo':123,'bar':456});set(0,'foo',999);get(0).bar}" << 456 << "";
+
+ QTest::newRow("move1a") << "{append({'foo':123});append({'foo':456});move(0,1,1);count}" << 2 << "";
+ QTest::newRow("move1b") << "{append({'foo':123});append({'foo':456});move(0,1,1);get(0).foo}" << 456 << "";
+ QTest::newRow("move1c") << "{append({'foo':123});append({'foo':456});move(0,1,1);get(1).foo}" << 123 << "";
+ QTest::newRow("move1d") << "{append({'foo':123});append({'foo':456});move(1,0,1);get(0).foo}" << 456 << "";
+ QTest::newRow("move1e") << "{append({'foo':123});append({'foo':456});move(1,0,1);get(1).foo}" << 123 << "";
+ QTest::newRow("move2a") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);count}" << 3 << "";
+ QTest::newRow("move2b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(0).foo}" << 789 << "";
+ QTest::newRow("move2c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(1).foo}" << 123 << "";
+ QTest::newRow("move2d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(2).foo}" << 456 << "";
+
+ // Structured model
+
+ // XXX todo
+}
+
+void tst_QmlListModel::dynamic()
+{
+ QFETCH(QString, script);
+ QFETCH(int, result);
+ QFETCH(QString, warning);
+
+ QmlEngine engine;
+ QmlListModel model;
+ QmlEngine::setContextForObject(&model,engine.rootContext());
+ engine.rootContext()->addDefaultObject(&model);
+ QmlExpression e(engine.rootContext(), script, &model);
+ if (!warning.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, warning.toLatin1());
+ int actual = e.value().toInt();
+ if (e.hasError())
+ qDebug() << e.error(); // errors not expected
+ QVERIFY(!e.hasError());
+ QCOMPARE(actual,result);
+}
+
+QTEST_MAIN(tst_QmlListModel)
+
+#include "tst_qmllistmodel.moc"
diff --git a/tests/auto/declarative/visual/webview/embedding/egg.qml b/tests/auto/declarative/visual/webview/embedding/egg.qml
new file mode 100644
index 0000000..a9019d1
--- /dev/null
+++ b/tests/auto/declarative/visual/webview/embedding/egg.qml
@@ -0,0 +1,27 @@
+import Qt 4.6
+
+Item {
+ property var period : 250
+ property var color : "black"
+ id: root
+
+ Item {
+ x: root.width/2
+ y: root.height/2
+ Rectangle {
+ radius: width/2
+ color: root.color
+ x: -width/2
+ y: -height/2
+ width: root.width*1.5
+ height: root.height*1.5
+ }
+ rotation: NumberAnimation {
+ from: 0
+ to: 360
+ repeat: true
+ running: true
+ duration: root.period
+ }
+ }
+}
diff --git a/tests/auto/declarative/visual/webview/embedding/nesting.html b/tests/auto/declarative/visual/webview/embedding/nesting.html
new file mode 100644
index 0000000..6e81689
--- /dev/null
+++ b/tests/auto/declarative/visual/webview/embedding/nesting.html
@@ -0,0 +1,9 @@
+<html>
+<head><title>Nesting</title>
+<link rel="icon" sizes="48x48" href="basic.png">
+</head>
+<body bgcolor="green">
+<h1>Nesting</h1>
+This is a test...
+<OBJECT data=egg.qml TYPE=application/x-qt-plugin width=50 height=70 period=2000 color=white></OBJECT>
+... with a spinning QML egg nested in it.
diff --git a/tests/auto/declarative/visual/webview/embedding/nesting.qml b/tests/auto/declarative/visual/webview/embedding/nesting.qml
new file mode 100644
index 0000000..0d76579
--- /dev/null
+++ b/tests/auto/declarative/visual/webview/embedding/nesting.qml
@@ -0,0 +1,8 @@
+import Qt 4.6
+
+WebView {
+ width: 300
+ height: 200
+ url: "nesting.html"
+ settings.pluginsEnabled: true
+}