Remove QModelIndexList value type, use Array instead
We implement this by adding QModelIndexList to the set of sequence types. Change-Id: If7e0e88ab0c2916c2b65a926f8241549520d7391 Reviewed-by: Stephen Kelly <steveire@gmail.com>
This commit is contained in:
parent
226419514e
commit
ae1c3eba3e
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
QVERIFY(object->property("propIsArray").toBool());
|
||||
QVERIFY(object->property("varPropIsArray").toBool());
|
||||
QVERIFY(object->property("varIsArray").toBool());
|
||||
|
||||
QVariant milVariant = object->property("modelIndexList");
|
||||
QCOMPARE(milVariant.userType(), qMetaTypeId<QModelIndexList>());
|
||||
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());
|
||||
|
||||
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));
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue