Remove QItemSelection value-type, use Array instead

We implement this by adding QItemSelection to the
set of sequence types.

Change-Id: Ia3db376c806d8f062639e22c7f4bf392f114c266
Reviewed-by: Stephen Kelly <steveire@gmail.com>
This commit is contained in:
Gabriel de Dietrich 2015-03-06 19:27:22 +01:00
parent ae1c3eba3e
commit 0271609d51
7 changed files with 62 additions and 88 deletions

View File

@ -75,7 +75,8 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
F(QString, String, QList<QString>, QString()) \
F(QString, QString, QStringList, QString()) \
F(QUrl, Url, QList<QUrl>, QUrl()) \
F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex())
F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \
F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange())
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QString &element)
{
@ -98,6 +99,13 @@ static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, co
return QV4::QQmlValueTypeWrapper::create(engine, QVariant(element), vtmo, QMetaType::QModelIndex);
}
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QItemSelectionRange &element)
{
int metaTypeId = qMetaTypeId<QItemSelectionRange>();
const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(metaTypeId);
return QV4::QQmlValueTypeWrapper::create(engine, QVariant::fromValue(element), vtmo, metaTypeId);
}
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *, qreal element)
{
return QV4::Encode(element);
@ -128,6 +136,11 @@ static QString convertElementToString(const QModelIndex &element)
return reinterpret_cast<const QQmlModelIndexValueType *>(&element)->toString();
}
static QString convertElementToString(const QItemSelectionRange &element)
{
return reinterpret_cast<const QQmlItemSelectionRangeValueType *>(&element)->toString();
}
static QString convertElementToString(qreal element)
{
QString qstr;
@ -168,6 +181,14 @@ template <> QModelIndex convertValueToElement(const Value &value)
return QModelIndex();
}
template <> QItemSelectionRange convertValueToElement(const Value &value)
{
const QQmlValueTypeWrapper *v = value_cast<QQmlValueTypeWrapper>(value);
if (v)
return v->toVariant().value<QItemSelectionRange>();
return QItemSelectionRange();
}
template <> qreal convertValueToElement(const Value &value)
{
return value.toNumber();
@ -567,6 +588,9 @@ DEFINE_OBJECT_VTABLE(QQmlUrlList);
typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList;
template<>
DEFINE_OBJECT_VTABLE(QQmlQModelIndexList);
typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList;
template<>
DEFINE_OBJECT_VTABLE(QQmlQItemSelectionRangeList);
typedef QQmlSequence<QList<bool> > QQmlBoolList;
template<>
DEFINE_OBJECT_VTABLE(QQmlBoolList);

View File

@ -65,7 +65,6 @@ QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl()
// See types wrapped in qqmlmodelindexvaluetype_p.h
qRegisterMetaType<QItemSelectionRange>();
qRegisterMetaType<QItemSelection>();
}
QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl()
@ -113,8 +112,6 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
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;

View File

@ -100,27 +100,11 @@
\section1 QItemSelection
\l QItemSelection exposes the following properties and functions as part of
its \l QList API:
Similarly to QModelIndexList, \l QItemSelection is exposed in QML as a JavaScript
array of QItemSelectionRanges. Conversions are automatically made from and to C++.
In fact, any JavaScript array can be converted back to QItemSelection, with
non-QItemSelectionRange objects replaced by empty QItemSelectionRanges.
\list
\li \b length : int
\li object \b{at}(int i)
\li void \b{append}(object o)
\li void \b{prepend}(o)
\li void \b{insert}(int i, object o)
\li void \b{removeFirst}()
\li void \b{removeLast}()
\li void \b{removeAt}(int i)
\endlist
In addition, \l QItemSelection also exposes the following functions:
\list
\li void \b{select}(QModelIndex topLeft, QModelIndex bottomRight)
\li bool \b{contains}(QModelIndex index)
\li void \b{merge}(QItemSelection other, QItemSelectionModel::SelectionFlags command)
\endlist
\sa ItemSelectionModel
*/

View File

@ -150,50 +150,6 @@ public:
inline bool isEmpty() const { return v.isEmpty(); }
};
template<typename V, typename T>
QString q_listToString(const QList<T> &list, const QLatin1String &typeName)
{
QString result = typeName;
result.append(QLatin1Char('('));
for (typename QList<T>::size_type i = 0; i < list.count(); ++i) {
if (i)
result.append(QLatin1String(", "));
result.append(reinterpret_cast<const V *>(&list.at(i))->toString());
}
return result.append(QLatin1Char(')'));
}
// Invokable QList<T> API forwarding for value types
#define QLISTVALUETYPE_QML_API(T) \
Q_PROPERTY(int length READ length FINAL) \
Q_INVOKABLE T at(int i) { return v.at(i); } \
Q_INVOKABLE void append(const T &o) { v.append(o); } \
Q_INVOKABLE void prepend(const T &o) { v.prepend(o); } \
Q_INVOKABLE void insert(int i, const T &o) { v.insert(i, o); } \
Q_INVOKABLE void removeFirst() { v.removeFirst(); } \
Q_INVOKABLE void removeLast() { v.removeLast(); } \
Q_INVOKABLE void removeAt(int i) { v.removeAt(i); } \
int length() const { return v.length(); }
struct QQmlItemSelectionValueType
{
QItemSelection v;
Q_GADGET
public:
Q_INVOKABLE QString toString()
{ return q_listToString<QQmlItemSelectionRangeValueType>(v, QLatin1String("QItemSelection")); }
Q_INVOKABLE void select(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ v.select(topLeft, bottomRight); }
Q_INVOKABLE bool contains(const QModelIndex &index) const
{ return v.contains(index); }
Q_INVOKABLE void merge(const QItemSelection &other, int command)
{ v.merge(other, QItemSelectionModel::SelectionFlags(command)); }
QLISTVALUETYPE_QML_API(QItemSelectionRange)
};
#undef QLISTVALUETYPE_INVOKABLE_API
QT_END_NAMESPACE

View File

@ -1,9 +1,10 @@
import Test 1.0
ItemModelsTest {
property var itemSelection
property int count
property bool contains: false
property var itemSelectionBinding: itemSelection
property var itemSelectionRead
function range(top, bottom, left, right, parent) {
if (parent === undefined)
@ -14,23 +15,15 @@ ItemModelsTest {
}
onModelChanged: {
itemSelection = createItemSelection()
itemSelection.prepend(range(0, 0, 0, 5))
itemSelection.append(range(0, 5, 0, 0))
itemSelection = []
itemSelection.push(range(0, 0, 0, 5))
itemSelection.push(range(0, 5, 0, 0))
for (var i = 0; i < 3; i++)
itemSelection.insert(i, range(i, i + 1, i + 2, i + 3))
itemSelection.splice(i, 0, range(i, i + 1, i + 2, i + 3))
var itemSelection2 = createItemSelection()
for (i = 3; i < 6; i++)
itemSelection2.select(model.index(i, i + 1), model.index(i + 2, i + 3))
itemSelection.merge(itemSelection2, 2 /*ItemSelectionModel.Select*/)
itemSelectionRead = itemSelection
count = itemSelection.length
contains = itemSelection.contains(model.index(0, 0))
itemSelection.removeAt(3)
itemSelection.removeFirst()
itemSelection.removeLast()
contains = itemSelection.some(function (range, idx) { return range.contains(model.index(0, 0)) })
}
}

View File

@ -46,6 +46,7 @@ class ItemModelsTest : public QObject
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)
Q_PROPERTY(QItemSelection itemSelection READ itemSelection WRITE setItemSelection NOTIFY changed)
public:
ItemModelsTest(QObject *parent = 0)
@ -84,6 +85,11 @@ public:
return list;
}
QItemSelection itemSelection() const
{
return m_itemSelection;
}
void emitChanged()
{
emit changed();
@ -161,6 +167,15 @@ public slots:
emit changed();
}
void setItemSelection(QItemSelection arg)
{
if (m_itemSelection == arg)
return;
m_itemSelection = arg;
emit changed();
}
signals:
void changed();
@ -174,6 +189,7 @@ private:
QPersistentModelIndex m_persistentModelIndex;
QAbstractItemModel *m_model;
QModelIndexList m_modelIndexList;
QItemSelection m_itemSelection;
};
#endif // TESTTYPES_H

View File

@ -184,14 +184,18 @@ void tst_qqmlitemmodels::itemSelection()
TestModel model(10, 10);
object->setModel(&model);
QCOMPARE(object->property("count").toInt(), 8);
QCOMPARE(object->property("count").toInt(), 5);
QCOMPARE(object->property("contains").toBool(), true);
QVariant milVariant = object->property("itemSelection");
QCOMPARE(milVariant.userType(), qMetaTypeId<QItemSelection>());
const char *propNames[] = { "itemSelectionRead", "itemSelectionBinding", 0 };
for (const char **name = propNames; *name; name++) {
QVariant isVariant = object->property(*name);
QCOMPARE(isVariant.userType(), qMetaTypeId<QItemSelection>());
const QItemSelection &mil = milVariant.value<QItemSelection>();
QCOMPARE(mil.count(), 5);
const QItemSelection &sel = isVariant.value<QItemSelection>();
QCOMPARE(sel.count(), object->itemSelection().count());
QCOMPARE(sel, object->itemSelection());
}
}
void tst_qqmlitemmodels::modelIndexList()