aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Watson <glenn.watson@nokia.com>2012-06-26 14:52:27 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-26 23:28:55 +0200
commitfb5c74a07dac7deedb9ab3b8b4390941e5dd0762 (patch)
tree191f686acfa82176cda48207909b9643e11a36a7
parentfe73fabad96f443247c6334b2c1b6ef59401c2c8 (diff)
Support JS Date object in ListModel with static roles.
ListModel uses static roles by default for performance reasons. Add JS Date object to list of supported types in this mode, via implicit conversion to QDateTime. Task-number: QTBUG-24456 Change-Id: Ifaa1a8d16290e87b61239ed351a949d66a02990c Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--src/qml/qml/qquicklistmodel.cpp75
-rw-r--r--src/qml/qml/qquicklistmodel_p_p.h4
-rw-r--r--tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp36
3 files changed, 112 insertions, 3 deletions
diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/qml/qquicklistmodel.cpp
index 03f9e3a790..e865d847a8 100644
--- a/src/qml/qml/qquicklistmodel.cpp
+++ b/src/qml/qml/qquicklistmodel.cpp
@@ -78,7 +78,7 @@ static bool isMemoryUsed(const char *mem)
static QString roleTypeName(ListLayout::Role::DataType t)
{
QString result;
- const char *roleTypeNames[] = { "String", "Number", "Bool", "List", "QObject", "VariantMap" };
+ const char *roleTypeNames[] = { "String", "Number", "Bool", "List", "QObject", "VariantMap", "DateTime" };
if (t > ListLayout::Role::Invalid && t < ListLayout::Role::MaxDataType)
result = QString::fromLatin1(roleTypeNames[t]);
@@ -119,8 +119,8 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(v8::Handle<v8::String> key,
const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::Role::DataType type)
{
- const int dataSizes[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QQmlGuard<QObject>), sizeof(QVariantMap) };
- const int dataAlignments[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QObject *), sizeof(QVariantMap) };
+ const int dataSizes[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QQmlGuard<QObject>), sizeof(QVariantMap), sizeof(QDateTime) };
+ const int dataAlignments[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QObject *), sizeof(QVariantMap), sizeof(QDateTime) };
Role *r = new Role;
r->name = key;
@@ -448,6 +448,10 @@ void ListModel::set(int elementIndex, v8::Handle<v8::Object> object, QList<int>
} else if (propertyValue->IsBoolean()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool);
roleIndex = e->setBoolProperty(r, propertyValue->BooleanValue());
+ } else if (propertyValue->IsDate()) {
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
+ QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(propertyValue)->NumberValue());
+ roleIndex = e->setDateTimeProperty(r, dt);
} else if (propertyValue->IsObject()) {
QV8ObjectResource *r = (QV8ObjectResource *) propertyValue->ToObject()->GetExternalResource();
if (r && r->resourceType() == QV8ObjectResource::QObjectType) {
@@ -520,6 +524,12 @@ void ListModel::set(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *
if (r.type == ListLayout::Role::Bool) {
e->setBoolPropertyFast(r, propertyValue->BooleanValue());
}
+ } else if (propertyValue->IsDate()) {
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
+ if (r.type == ListLayout::Role::DateTime) {
+ QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(propertyValue)->NumberValue());
+ e->setDateTimePropertyFast(r, dt);
+ }
} else if (propertyValue->IsObject()) {
QV8ObjectResource *r = (QV8ObjectResource *) propertyValue->ToObject()->GetExternalResource();
if (r && r->resourceType() == QV8ObjectResource::QObjectType) {
@@ -651,6 +661,17 @@ QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role)
return map;
}
+QDateTime *ListElement::getDateTimeProperty(const ListLayout::Role &role)
+{
+ QDateTime *dt = 0;
+
+ char *mem = getPropertyMemory(role);
+ if (isMemoryUsed<QDateTime>(mem))
+ dt = reinterpret_cast<QDateTime *>(mem);
+
+ return dt;
+}
+
QQmlGuard<QObject> *ListElement::getGuardProperty(const ListLayout::Role &role)
{
char *mem = getPropertyMemory(role);
@@ -736,6 +757,14 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQuickList
}
}
break;
+ case ListLayout::Role::DateTime:
+ {
+ if (isMemoryUsed<QDateTime>(mem)) {
+ QDateTime *dt = reinterpret_cast<QDateTime *>(mem);
+ data = *dt;
+ }
+ }
+ break;
default:
break;
}
@@ -881,6 +910,23 @@ int ListElement::setVariantMapProperty(const ListLayout::Role &role, QVariantMap
return roleIndex;
}
+int ListElement::setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt)
+{
+ int roleIndex = -1;
+
+ if (role.type == ListLayout::Role::DateTime) {
+ char *mem = getPropertyMemory(role);
+ if (isMemoryUsed<QDateTime>(mem)) {
+ QDateTime *dt = reinterpret_cast<QDateTime *>(mem);
+ dt->~QDateTime();
+ }
+ new (mem) QDateTime(dt);
+ roleIndex = role.index;
+ }
+
+ return roleIndex;
+}
+
void ListElement::setStringPropertyFast(const ListLayout::Role &role, const QString &s)
{
char *mem = getPropertyMemory(role);
@@ -921,6 +967,12 @@ void ListElement::setVariantMapFast(const ListLayout::Role &role, v8::Handle<v8:
*map = eng->variantMapFromJS(o);
}
+void ListElement::setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt)
+{
+ char *mem = getPropertyMemory(role);
+ new (mem) QDateTime(dt);
+}
+
void ListElement::clearProperty(const ListLayout::Role &role)
{
switch (role.type) {
@@ -939,6 +991,9 @@ void ListElement::clearProperty(const ListLayout::Role &role)
case ListLayout::Role::QObject:
setQObjectProperty(role, 0);
break;
+ case ListLayout::Role::DateTime:
+ setDateTimeProperty(role, QDateTime());
+ break;
case ListLayout::Role::VariantMap:
setVariantMapProperty(role, 0);
break;
@@ -998,6 +1053,7 @@ void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *tar
case ListLayout::Role::String:
case ListLayout::Role::Number:
case ListLayout::Role::Bool:
+ case ListLayout::Role::DateTime:
{
QVariant v = src->getProperty(srcRole, 0, 0);
target->setVariantProperty(targetRole, v);
@@ -1052,6 +1108,13 @@ void ListElement::destroy(ListLayout *layout)
map->~QMap();
}
break;
+ case ListLayout::Role::DateTime:
+ {
+ QDateTime *dt = getDateTimeProperty(r);
+ if (dt)
+ dt->~QDateTime();
+ }
+ break;
default:
// other types don't need explicit cleanup.
break;
@@ -1088,6 +1151,9 @@ int ListElement::setVariantProperty(const ListLayout::Role &role, const QVariant
roleIndex = setVariantMapProperty(role, &map);
}
break;
+ case ListLayout::Role::DateTime:
+ roleIndex = setDateTimeProperty(role, d.toDateTime());
+ break;
default:
break;
}
@@ -1124,6 +1190,9 @@ int ListElement::setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Valu
}
} else if (d->IsBoolean()) {
roleIndex = setBoolProperty(role, d->BooleanValue());
+ } else if (d->IsDate()) {
+ QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(d)->NumberValue());
+ roleIndex = setDateTimeProperty(role, dt);
} else if (d->IsObject()) {
QV8ObjectResource *r = (QV8ObjectResource *) d->ToObject()->GetExternalResource();
if (role.type == ListLayout::Role::QObject && r && r->resourceType() == QV8ObjectResource::QObjectType) {
diff --git a/src/qml/qml/qquicklistmodel_p_p.h b/src/qml/qml/qquicklistmodel_p_p.h
index f9256c9f0a..a006721f9c 100644
--- a/src/qml/qml/qquicklistmodel_p_p.h
+++ b/src/qml/qml/qquicklistmodel_p_p.h
@@ -197,6 +197,7 @@ public:
List,
QObject,
VariantMap,
+ DateTime,
MaxDataType
};
@@ -260,6 +261,7 @@ private:
int setQObjectProperty(const ListLayout::Role &role, QObject *o);
int setVariantMapProperty(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng);
int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
+ int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
void setDoublePropertyFast(const ListLayout::Role &role, double n);
@@ -267,6 +269,7 @@ private:
void setQObjectPropertyFast(const ListLayout::Role &role, QObject *o);
void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
void setVariantMapFast(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng);
+ void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
void clearProperty(const ListLayout::Role &role);
@@ -276,6 +279,7 @@ private:
QObject *getQObjectProperty(const ListLayout::Role &role);
QQmlGuard<QObject> *getGuardProperty(const ListLayout::Role &role);
QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
+ QDateTime *getDateTimeProperty(const ListLayout::Role &role);
inline char *getPropertyMemory(const ListLayout::Role &role);
diff --git a/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp b/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
index e94fe81024..e4045ebe88 100644
--- a/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
+++ b/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
@@ -125,6 +125,8 @@ private slots:
void string_to_list_crash();
void empty_element_warning();
void empty_element_warning_data();
+ void datetime();
+ void datetime_data();
};
bool tst_qquicklistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1226,6 +1228,40 @@ void tst_qquicklistmodel::empty_element_warning()
delete obj;
}
+void tst_qquicklistmodel::datetime_data()
+{
+ QTest::addColumn<QString>("qml");
+ QTest::addColumn<QDateTime>("expected");
+
+ QDateTime dt;
+ QDateTime dt0(QDate(1900, 1, 2), QTime( 8, 14));
+ QDateTime dt1(QDate(2000, 11, 22), QTime(10, 45));
+
+ QTest::newRow("dt0") << "{append({'date':dt0});get(0).date}" << dt0;
+ QTest::newRow("dt1") << "{append({'date':dt0});get(0).date=dt1;get(0).date}" << dt1;
+ QTest::newRow("dt2") << "{append({'date':dt0});set(0,{'date':dt1});get(0).date}" << dt1;
+ QTest::newRow("dt3") << "{append({'date':dt0});get(0).date=undefined;get(0).date}" << dt;
+}
+
+void tst_qquicklistmodel::datetime()
+{
+ QFETCH(QString, qml);
+ QFETCH(QDateTime, expected);
+
+ QQmlEngine engine;
+ QQuickListModel model;
+ QQmlEngine::setContextForObject(&model,engine.rootContext());
+ QDateTime dt0(QDate(1900, 1, 2), QTime( 8, 14));
+ QDateTime dt1(QDate(2000, 11, 22), QTime(10, 45));
+ engine.rootContext()->setContextProperty("dt0", dt0);
+ engine.rootContext()->setContextProperty("dt1", dt1);
+ engine.rootContext()->setContextObject(&model);
+ QQmlExpression e(engine.rootContext(), &model, qml);
+ QVariant result = e.evaluate();
+ QDateTime dtResult = result.toDateTime();
+ QVERIFY(expected == dtResult);
+}
+
QTEST_MAIN(tst_qquicklistmodel)
#include "tst_qquicklistmodel.moc"