aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/v8
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-08-02 10:04:16 +1000
committerQt by Nokia <qt-info@nokia.com>2011-08-02 08:50:21 +0200
commit0db6db0263defcd6ff84769b7d927d5a51606f6c (patch)
treeec30dca485b9cf576a70d4b232d6525f3d569c90 /src/declarative/qml/v8
parent29e71ca376f48bafc2105b656a702f3edd4501a8 (diff)
Add support for comparing value-type properties
This commit allows value-types to be compared with each other and with variants. It also adds a toString() function for each value type, to allow conversion to (and comparison with) string. Task-number: QTBUG-14731 Change-Id: I5bde2820917b2fe19b581724977398680617de34 Reviewed-on: http://codereview.qt.nokia.com/1636 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative/qml/v8')
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp13
-rw-r--r--src/declarative/qml/v8/qv8engine_p.h1
-rw-r--r--src/declarative/qml/v8/qv8valuetypewrapper.cpp63
-rw-r--r--src/declarative/qml/v8/qv8valuetypewrapper_p.h6
4 files changed, 82 insertions, 1 deletions
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp
index acbfb92b15..a538109c2c 100644
--- a/src/declarative/qml/v8/qv8engine.cpp
+++ b/src/declarative/qml/v8/qv8engine.cpp
@@ -42,6 +42,7 @@
#include "qv8engine_p.h"
#include "qv8contextwrapper_p.h"
+#include "qv8valuetypewrapper_p.h"
#include "qv8include_p.h"
#include "../../../3rdparty/javascriptcore/DateMath.h"
@@ -87,10 +88,20 @@ static bool ObjectComparisonCallback(v8::Local<v8::Object> lhs, v8::Local<v8::Ob
QV8ObjectResource::ResourceType rhst = rhsr->resourceType();
switch (lhst) {
+ case QV8ObjectResource::ValueTypeType:
+ if (rhst == QV8ObjectResource::ValueTypeType) {
+ return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->valueTypeWrapper()->toVariant(rhsr));
+ } else if (rhst == QV8ObjectResource::VariantType) {
+ return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->variantWrapper()->toVariant(rhsr));
+ }
+ break;
case QV8ObjectResource::VariantType:
- if (rhst == QV8ObjectResource::VariantType)
+ if (rhst == QV8ObjectResource::VariantType) {
return lhsr->engine->variantWrapper()->toVariant(lhsr) ==
lhsr->engine->variantWrapper()->toVariant(rhsr);
+ } else if (rhst == QV8ObjectResource::ValueTypeType) {
+ return rhsr->engine->valueTypeWrapper()->isEqual(rhsr, rhsr->engine->variantWrapper()->toVariant(lhsr));
+ }
break;
default:
break;
diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h
index b95e55002b..938454c901 100644
--- a/src/declarative/qml/v8/qv8engine_p.h
+++ b/src/declarative/qml/v8/qv8engine_p.h
@@ -265,6 +265,7 @@ public:
QV8TypeWrapper *typeWrapper() { return &m_typeWrapper; }
QV8ListWrapper *listWrapper() { return &m_listWrapper; }
QV8VariantWrapper *variantWrapper() { return &m_variantWrapper; }
+ QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; }
void *xmlHttpRequestData() { return m_xmlHttpRequestData; }
void *sqlDatabaseData() { return m_sqlDatabaseData; }
diff --git a/src/declarative/qml/v8/qv8valuetypewrapper.cpp b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
index f3100cf7b5..a55626061d 100644
--- a/src/declarative/qml/v8/qv8valuetypewrapper.cpp
+++ b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
@@ -103,15 +103,21 @@ QV8ValueTypeWrapper::~QV8ValueTypeWrapper()
void QV8ValueTypeWrapper::destroy()
{
+ qPersistentDispose(m_toString);
qPersistentDispose(m_constructor);
}
void QV8ValueTypeWrapper::init(QV8Engine *engine)
{
m_engine = engine;
+ m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction());
v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter);
ft->InstanceTemplate()->SetHasExternalResource(true);
+ ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
+ m_toString, v8::DEFAULT,
+ v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
}
@@ -166,6 +172,59 @@ QVariant QV8ValueTypeWrapper::toVariant(QV8ObjectResource *r)
}
}
+bool QV8ValueTypeWrapper::isEqual(QV8ObjectResource *r, const QVariant& value)
+{
+ Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType);
+ QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r);
+
+ if (resource->objectType == QV8ValueTypeResource::Reference) {
+ QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
+ if (reference->object) {
+ reference->type->read(reference->object, reference->property);
+ return reference->type->isEqual(value);
+ } else {
+ return false;
+ }
+ } else {
+ Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
+ QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
+ return (value == copy->value);
+ }
+}
+
+v8::Handle<v8::Value> QV8ValueTypeWrapper::ToStringGetter(v8::Local<v8::String> property,
+ const v8::AccessorInfo &info)
+{
+ Q_UNUSED(property);
+ return info.Data();
+}
+
+v8::Handle<v8::Value> QV8ValueTypeWrapper::ToString(const v8::Arguments &args)
+{
+ QV8ValueTypeResource *resource = v8_resource_cast<QV8ValueTypeResource>(args.This());
+ if (resource) {
+ if (resource->objectType == QV8ValueTypeResource::Reference) {
+ QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
+ if (reference->object) {
+ reference->type->read(reference->object, reference->property);
+ return resource->engine->toString(resource->type->toString());
+ } else {
+ return v8::Undefined();
+ }
+ } else {
+ Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
+ QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
+ QString result = copy->value.toString();
+ if (result.isEmpty() && !copy->value.canConvert(QVariant::String)) {
+ result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(copy->value.typeName()));
+ }
+ return resource->engine->toString(result);
+ }
+ } else {
+ return v8::Undefined();
+ }
+}
+
v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property,
const v8::AccessorInfo &info)
{
@@ -177,6 +236,10 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property
// We should probably just replace all value properties with dedicated accessors.
QByteArray propName = r->engine->toString(property).toUtf8();
+ if (propName == QByteArray("toString")) {
+ return r->engine->valueTypeWrapper()->m_toString;
+ }
+
int index = r->type->metaObject()->indexOfProperty(propName.constData());
if (index == -1)
return v8::Undefined();
diff --git a/src/declarative/qml/v8/qv8valuetypewrapper_p.h b/src/declarative/qml/v8/qv8valuetypewrapper_p.h
index d08d89392c..2582560c0f 100644
--- a/src/declarative/qml/v8/qv8valuetypewrapper_p.h
+++ b/src/declarative/qml/v8/qv8valuetypewrapper_p.h
@@ -77,7 +77,12 @@ public:
QVariant toVariant(v8::Handle<v8::Object>);
QVariant toVariant(QV8ObjectResource *);
+ static bool isEqual(QV8ObjectResource *, const QVariant& value);
+
private:
+ static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property,
+ const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> ToString(const v8::Arguments &args);
static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
const v8::AccessorInfo &info);
static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
@@ -86,6 +91,7 @@ private:
QV8Engine *m_engine;
v8::Persistent<v8::Function> m_constructor;
+ v8::Persistent<v8::Function> m_toString;
};
QT_END_NAMESPACE