aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp28
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp13
-rw-r--r--src/qml/types/qqmlitemmodels.qdoc17
-rw-r--r--src/qml/types/qqmlmodelindexvaluetype_p.h13
-rw-r--r--tests/auto/qml/qqmlitemmodels/data/modelindexlist.qml27
-rw-r--r--tests/auto/qml/qqmlitemmodels/testtypes.h42
-rw-r--r--tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp36
7 files changed, 128 insertions, 48 deletions
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index a7e3b22cd2..f7adf6eb18 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -41,6 +41,9 @@
#include <private/qv4scopedvalue_p.h>
#include "qv4runtime_p.h"
#include "qv4objectiterator_p.h"
+#include <private/qqmlvaluetypewrapper_p.h>
+#include <private/qqmlmodelindexvaluetype_p.h>
+#include <QtCore/qabstractitemmodel.h>
#include <algorithm>
@@ -71,7 +74,8 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
F(bool, Bool, QList<bool>, false) \
F(QString, String, QList<QString>, QString()) \
F(QString, QString, QStringList, QString()) \
- F(QUrl, Url, QList<QUrl>, QUrl())
+ F(QUrl, Url, QList<QUrl>, QUrl()) \
+ F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex())
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QString &element)
{
@@ -88,6 +92,12 @@ static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, co
return engine->newString(element.toString())->asReturnedValue();
}
+static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QModelIndex &element)
+{
+ const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(QMetaType::QModelIndex);
+ return QV4::QQmlValueTypeWrapper::create(engine, QVariant(element), vtmo, QMetaType::QModelIndex);
+}
+
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *, qreal element)
{
return QV4::Encode(element);
@@ -113,6 +123,11 @@ static QString convertElementToString(const QUrl &element)
return element.toString();
}
+static QString convertElementToString(const QModelIndex &element)
+{
+ return reinterpret_cast<const QQmlModelIndexValueType *>(&element)->toString();
+}
+
static QString convertElementToString(qreal element)
{
QString qstr;
@@ -145,6 +160,14 @@ template <> QUrl convertValueToElement(const Value &value)
return QUrl(value.toQString());
}
+template <> QModelIndex convertValueToElement(const Value &value)
+{
+ const QQmlValueTypeWrapper *v = value_cast<QQmlValueTypeWrapper>(value);
+ if (v)
+ return v->toVariant().toModelIndex();
+ return QModelIndex();
+}
+
template <> qreal convertValueToElement(const Value &value)
{
return value.toNumber();
@@ -541,6 +564,9 @@ DEFINE_OBJECT_VTABLE(QQmlIntList);
typedef QQmlSequence<QList<QUrl> > QQmlUrlList;
template<>
DEFINE_OBJECT_VTABLE(QQmlUrlList);
+typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList;
+template<>
+DEFINE_OBJECT_VTABLE(QQmlQModelIndexList);
typedef QQmlSequence<QList<bool> > QQmlBoolList;
template<>
DEFINE_OBJECT_VTABLE(QQmlBoolList);
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 2b3f78b676..6711ad2de9 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -64,7 +64,6 @@ QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl()
valueTypes[ii] = 0;
// See types wrapped in qqmlmodelindexvaluetype_p.h
- qRegisterMetaType<QModelIndexList>();
qRegisterMetaType<QItemSelectionRange>();
qRegisterMetaType<QItemSelection>();
}
@@ -112,18 +111,16 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
case QVariant::PersistentModelIndex:
return &QQmlPersistentModelIndexValueType::staticMetaObject;
default:
+ if (t == qMetaTypeId<QItemSelectionRange>())
+ return &QQmlItemSelectionRangeValueType::staticMetaObject;
+ if (t == qMetaTypeId<QItemSelection>())
+ return &QQmlItemSelectionValueType::staticMetaObject;
+
if (const QMetaObject *mo = QQml_valueTypeProvider()->metaObjectForMetaType(t))
return mo;
break;
}
- if (t == qMetaTypeId<QModelIndexList>())
- return &QQmlModelIndexListValueType::staticMetaObject;
- else if (t == qMetaTypeId<QItemSelectionRange>())
- return &QQmlItemSelectionRangeValueType::staticMetaObject;
- else if (t == qMetaTypeId<QItemSelection>())
- return &QQmlItemSelectionValueType::staticMetaObject;
-
QMetaType metaType(t);
if (metaType.flags() & QMetaType::IsGadget)
return metaType.metaObject();
diff --git a/src/qml/types/qqmlitemmodels.qdoc b/src/qml/types/qqmlitemmodels.qdoc
index 25c9321115..70059b07c6 100644
--- a/src/qml/types/qqmlitemmodels.qdoc
+++ b/src/qml/types/qqmlitemmodels.qdoc
@@ -60,6 +60,17 @@
should not store any QModelIndex. You can, however, store QPersistentModelIndexes
in a safe way.
+ \section1 QModelIndexList
+
+ \l QModelIndexList is exposed in QML as a JavaScript array. Conversions are
+ automatically made from and to C++. In fact, any JavaScript array can be
+ converted back to QModelIndexList, with non-QModelIndex objects replaced by
+ invalid QModelIndexes.
+
+ \note QModelIndex to QPersistentModelIndex conversion happens when accessing
+ the array elements because any QModelIndexList property retains reference
+ semantics when exposed this way.
+
\section1 \l QItemSelectionRange
\list
@@ -87,10 +98,10 @@
\li QItemSelectionRange \b{intersected}(QItemSelectionRange other)
\endlist
- \section1 \l QModelIndexList and \l QItemSelection
+ \section1 QItemSelection
- Both \l QModelIndexList and \l QItemSelection expose the following properties
- and functions as part of their \l QList API:
+ \l QItemSelection exposes the following properties and functions as part of
+ its \l QList API:
\list
\li \b length : int
diff --git a/src/qml/types/qqmlmodelindexvaluetype_p.h b/src/qml/types/qqmlmodelindexvaluetype_p.h
index 0e655ab3d7..e36f7a0d1e 100644
--- a/src/qml/types/qqmlmodelindexvaluetype_p.h
+++ b/src/qml/types/qqmlmodelindexvaluetype_p.h
@@ -175,19 +175,6 @@ QString q_listToString(const QList<T> &list, const QLatin1String &typeName)
Q_INVOKABLE void removeAt(int i) { v.removeAt(i); } \
int length() const { return v.length(); }
-struct QQmlModelIndexListValueType
-{
- QModelIndexList v;
-
- Q_GADGET
-
-public:
- Q_INVOKABLE QString toString()
- { return q_listToString<QQmlModelIndexValueType>(v, QLatin1String("")); }
-
- QLISTVALUETYPE_QML_API(QModelIndex)
-};
-
struct QQmlItemSelectionValueType
{
QItemSelection v;
diff --git a/tests/auto/qml/qqmlitemmodels/data/modelindexlist.qml b/tests/auto/qml/qqmlitemmodels/data/modelindexlist.qml
index 44393392d3..389c5daaf5 100644
--- a/tests/auto/qml/qqmlitemmodels/data/modelindexlist.qml
+++ b/tests/auto/qml/qqmlitemmodels/data/modelindexlist.qml
@@ -1,21 +1,30 @@
import Test 1.0
ItemModelsTest {
- property var modelIndexList
property int count
+ property var modelIndexListCopy
+ property var modelIndexListRead
+ property var modelIndexListBinding: modelIndexList
+ property bool varPropIsArray
+ property bool varIsArray
+ property bool propIsArray
onModelChanged: {
- modelIndexList = createModelIndexList()
- modelIndexList.prepend(model.index(0, 0))
- modelIndexList.append(model.index(1, 1))
+ var jsModelIndexList = []
for (var i = 0; i < 3; i++)
- modelIndexList.insert(i, model.index(2 + i, 2 + i))
+ jsModelIndexList.push(model.index(2 + i, 2 + i))
+ jsModelIndexList.push("Hi Bronsky!")
+ modelIndex = jsModelIndexList[0]
count = modelIndexList.length
- modelIndex = modelIndexList.at(0)
+ propIsArray = modelIndexList instanceof Array
+ modelIndexList = jsModelIndexList
+ modelIndexListRead = modelIndexList
- modelIndexList.removeAt(3)
- modelIndexList.removeFirst()
- modelIndexList.removeLast()
+ modelIndexListCopy = someModelIndexList()
+ varPropIsArray = modelIndexListCopy instanceof Array
+
+ jsModelIndexList = someModelIndexList()
+ varIsArray = jsModelIndexList instanceof Array
}
}
diff --git a/tests/auto/qml/qqmlitemmodels/testtypes.h b/tests/auto/qml/qqmlitemmodels/testtypes.h
index 5345609cd3..d61064fcad 100644
--- a/tests/auto/qml/qqmlitemmodels/testtypes.h
+++ b/tests/auto/qml/qqmlitemmodels/testtypes.h
@@ -45,8 +45,15 @@ class ItemModelsTest : public QObject
Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(QModelIndex modelIndex READ modelIndex WRITE setModelIndex NOTIFY changed)
Q_PROPERTY(QPersistentModelIndex persistentModelIndex READ persistentModelIndex WRITE setPersistentModelIndex NOTIFY changed)
+ Q_PROPERTY(QModelIndexList modelIndexList READ modelIndexList WRITE setModelIndexList NOTIFY changed)
public:
+ ItemModelsTest(QObject *parent = 0)
+ : QObject(parent)
+ , m_model(0)
+ {
+ }
+
QModelIndex modelIndex() const
{
return m_modelIndex;
@@ -57,6 +64,26 @@ public:
return m_persistentModelIndex;
}
+ QModelIndexList modelIndexList()
+ {
+ static bool firstTime = true;
+ if (firstTime && m_model && m_modelIndexList.isEmpty()) {
+ firstTime = false;
+ for (int i = 0; i < m_model->rowCount(); i++)
+ m_modelIndexList << m_model->index(i, 0);
+ }
+ return m_modelIndexList;
+ }
+
+ Q_INVOKABLE QModelIndexList someModelIndexList() const
+ {
+ QModelIndexList list;
+ if (m_model)
+ for (int i = 0; i < m_model->rowCount(); i++)
+ list << m_model->index(i, 0);
+ return list;
+ }
+
void emitChanged()
{
emit changed();
@@ -82,11 +109,6 @@ public:
return QModelIndex();
}
- Q_INVOKABLE QModelIndexList createModelIndexList() const
- {
- return QModelIndexList();
- }
-
Q_INVOKABLE QItemSelectionRange createItemSelectionRange(const QModelIndex &tl, const QModelIndex &br) const
{
return QItemSelectionRange(tl, br);
@@ -130,6 +152,15 @@ public slots:
emit modelChanged(arg);
}
+ void setModelIndexList(QModelIndexList arg)
+ {
+ if (m_modelIndexList == arg)
+ return;
+
+ m_modelIndexList = arg;
+ emit changed();
+ }
+
signals:
void changed();
@@ -142,6 +173,7 @@ private:
QModelIndex m_modelIndex;
QPersistentModelIndex m_persistentModelIndex;
QAbstractItemModel *m_model;
+ QModelIndexList m_modelIndexList;
};
#endif // TESTTYPES_H
diff --git a/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp b/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp
index 84e8011685..cd00593ee6 100644
--- a/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp
+++ b/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp
@@ -198,17 +198,35 @@ void tst_qqmlitemmodels::modelIndexList()
{
INIT_TEST_OBJECT("modelindexlist.qml", object);
TestModel model(10, 10);
+ model.fetchMore(QModelIndex());
object->setModel(&model);
- QCOMPARE(object->property("count").toInt(), 5);
-
- QVariant milVariant = object->property("modelIndexList");
- QCOMPARE(milVariant.userType(), qMetaTypeId<QModelIndexList>());
-
- const QModelIndexList &mil = milVariant.value<QModelIndexList>();
- QCOMPARE(mil.count(), 2);
- QCOMPARE(mil.at(0), model.index(3, 3));
- QCOMPARE(mil.at(1), model.index(4, 4));
+ QVERIFY(object->property("propIsArray").toBool());
+ QVERIFY(object->property("varPropIsArray").toBool());
+ QVERIFY(object->property("varIsArray").toBool());
+
+ QCOMPARE(object->property("count").toInt(), 10);
+ const QModelIndexList &mil = object->modelIndexList();
+ QCOMPARE(mil.count(), 4);
+ for (int i = 0; i < 3; i++)
+ QCOMPARE(mil.at(i), model.index(2 + i, 2 + i));
+ QCOMPARE(mil.at(3), QModelIndex()); // The string inserted at the end should result in an invalid index
+ QCOMPARE(mil.at(0), object->modelIndex());
+
+ QVariant cppMILVariant = object->property("modelIndexListCopy");
+ QCOMPARE(cppMILVariant.userType(), qMetaTypeId<QModelIndexList>());
+ QModelIndexList someMIL = object->someModelIndexList();
+ QCOMPARE(cppMILVariant.value<QModelIndexList>(), someMIL);
+
+ const char *propNames[] = { "modelIndexListRead", "modelIndexListBinding", 0 };
+ for (const char **name = propNames; *name; name++) {
+ QVariant milVariant = object->property(*name);
+ QCOMPARE(milVariant.userType(), qMetaTypeId<QModelIndexList>());
+
+ const QModelIndexList &milProp = milVariant.value<QModelIndexList>();
+ QCOMPARE(milProp.count(), mil.count());
+ QCOMPARE(milProp, mil);
+ }
}
#undef INIT_TEST_OBJECT