summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-04-13 02:24:13 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-04-13 02:24:13 (GMT)
commit3e94b3a77affeef80544e48949e018ced4e0d96e (patch)
tree621251f4fd85ced80d80e15f8d120e90bc095585 /src/declarative/qml
parente9a0067ef4b272f1893522959dc15561970590ea (diff)
parentff0020481398e7c109973949260a42711c4cdcdc (diff)
downloadQt-3e94b3a77affeef80544e48949e018ced4e0d96e.zip
Qt-3e94b3a77affeef80544e48949e018ced4e0d96e.tar.gz
Qt-3e94b3a77affeef80544e48949e018ced4e0d96e.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml: (147 commits) doc fixes Don't test XmlListModel examples on platforms without QtXmlPatterns More error output for QML_IMPORT_TRACE=1 Fix declarative examples autotest, avoid using native separators Doc: update Rectangle smooth painting screenshot. Add some TextInput properties and methods Remove GraphicsObjectContainer from the documentation. import Qt 4.6 -> import Qt 4.7 Move documentation code to snippet. Test fix. Fix test Fix test on QWS. Fix PathView crash. Make bindings dump more useful Improve font value type documentation. coding conventions Doc fixes Warning Read Maemo orientation at startup Exclude gestures from examples autotest ...
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qdeclarative.h32
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp37
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp137
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp249
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager.cpp13
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp1
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecontextscriptclass.cpp6
-rw-r--r--src/declarative/qml/qdeclarativecontextscriptclass_p.h6
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp3
-rw-r--r--src/declarative/qml/qdeclarativedeclarativedata_p.h24
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp242
-rw-r--r--src/declarative/qml/qdeclarativeengine.h6
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h8
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp71
-rw-r--r--src/declarative/qml/qdeclarativeexpression_p.h10
-rw-r--r--src/declarative/qml/qdeclarativeinstruction.cpp8
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h9
-rw-r--r--src/declarative/qml/qdeclarativelistscriptclass.cpp4
-rw-r--r--src/declarative/qml/qdeclarativelistscriptclass_p.h6
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp17
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h5
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp102
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass_p.h14
-rw-r--r--src/declarative/qml/qdeclarativeparser.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h1
-rw-r--r--src/declarative/qml/qdeclarativescriptclass_p.h89
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp16
-rw-r--r--src/declarative/qml/qdeclarativestringconverters.cpp8
-rw-r--r--src/declarative/qml/qdeclarativetypenamescriptclass.cpp6
-rw-r--r--src/declarative/qml/qdeclarativetypenamescriptclass_p.h7
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp46
-rw-r--r--src/declarative/qml/qdeclarativevaluetype_p.h7
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp8
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass_p.h6
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp53
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp3
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp69
-rw-r--r--src/declarative/qml/qml.pri1
41 files changed, 785 insertions, 553 deletions
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 7c7f6e5..6e36d4f 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -119,6 +119,38 @@ int qmlRegisterType()
}
template<typename T>
+int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+{
+ QByteArray name(T::staticMetaObject.className());
+
+ QByteArray pointerName(name + '*');
+ QByteArray listName("QDeclarativeListProperty<" + name + ">");
+
+ QDeclarativePrivate::RegisterType type = {
+ 0,
+
+ qRegisterMetaType<T *>(pointerName.constData()),
+ qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
+ 0, 0,
+
+ uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+
+ QDeclarativePrivate::attachedPropertiesFunc<T>(),
+ QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
+
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(),
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
+
+ 0, 0,
+
+ 0
+ };
+
+ return QDeclarativePrivate::registerType(type);
+}
+
+template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
QByteArray name(T::staticMetaObject.className());
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 71cf3cb..e172a8b 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -126,7 +126,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
QDeclarativeBindingData *data = d->bindingData();
- if (!data->enabled)
+ if (!data->enabled || !data->context() || !data->context()->engine)
return;
data->addref();
@@ -148,14 +148,37 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
idx, a);
} else {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context()->engine);
+
bool isUndefined = false;
- QVariant value = this->value(&isUndefined);
+ QVariant value;
+
+ QScriptValue scriptValue = d->scriptValue(0, &isUndefined);
+ if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) {
+ value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >());
+ } else {
+ value = ep->scriptValueToVariant(scriptValue, data->property.propertyType());
+ if (value.userType() == QMetaType::QObjectStar && !qvariant_cast<QObject*>(value)) {
+ // If the object is null, we extract the predicted type. While this isn't
+ // 100% reliable, in many cases it gives us better error messages if we
+ // assign this null-object to an incompatible property
+ int type = ep->objectClass->objectType(scriptValue);
+ QObject *o = 0;
+ value = QVariant(type, (void *)&o);
+ }
+ }
- if (isUndefined && !data->error.isValid() && data->property.isResettable()) {
+ if (data->error.isValid()) {
+
+ } else if (isUndefined && data->property.isResettable()) {
data->property.reset();
- } else if (isUndefined && !data->error.isValid()) {
+ } else if (isUndefined && data->property.propertyType() == qMetaTypeId<QVariant>()) {
+
+ QDeclarativePropertyPrivate::write(data->property, QVariant(), flags);
+
+ } else if (isUndefined) {
QUrl url = QUrl(data->url);
int line = data->line;
@@ -166,7 +189,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
data->error.setColumn(-1);
data->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(data->property.propertyType())));
- } else if (!isUndefined && data->property.object() &&
+ } else if (data->property.object() &&
!QDeclarativePropertyPrivate::write(data->property, value, flags)) {
QUrl url = QUrl(data->url);
@@ -187,9 +210,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
}
if (data->error.isValid()) {
- QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)?
- QDeclarativeEnginePrivate::get(data->context()->engine):0;
- if (!data->addError(p))
+ if (!data->addError(ep))
qWarning().nospace() << qPrintable(this->error().toString());
} else {
data->removeError();
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 53143d5..0c824fc 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL);
DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER);
DEFINE_BOOL_CONFIG_OPTION(qmlDisableFastProperties, QML_DISABLE_FAST_PROPERTIES);
+DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties);
@@ -137,7 +138,7 @@ public:
Subscription *subscriptions;
QScriptDeclarativeClass::PersistentIdentifier *identifiers;
- void run(Binding *);
+ void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
const char *programData;
Binding *m_bindings;
@@ -147,7 +148,7 @@ public:
void init();
void run(int instr, QDeclarativeContextData *context,
- QDeclarativeDelayedError *error, QObject *scope, QObject *output);
+ QDeclarativeDelayedError *error, QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags);
inline void unsubscribe(int subIndex);
@@ -246,9 +247,9 @@ int QDeclarativeCompiledBindingsPrivate::Binding::propertyIndex()
return property & 0xFFFF;
}
-void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags)
+void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
- parent->run(this);
+ parent->run(this, flags);
}
void QDeclarativeCompiledBindingsPrivate::Binding::destroy()
@@ -270,13 +271,13 @@ int QDeclarativeCompiledBindings::qt_metacall(QMetaObject::Call c, int id, void
quint32 count = *reeval;
++reeval;
for (quint32 ii = 0; ii < count; ++ii) {
- d->run(d->m_bindings + reeval[ii]);
+ d->run(d->m_bindings + reeval[ii], QDeclarativePropertyPrivate::DontRemoveBinding);
}
}
return -1;
}
-void QDeclarativeCompiledBindingsPrivate::run(Binding *binding)
+void QDeclarativeCompiledBindingsPrivate::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
{
Q_Q(QDeclarativeCompiledBindings);
@@ -319,12 +320,11 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding)
vt->read(binding->target, binding->property & 0xFFFF);
QObject *target = vt;
- run(binding->index, context, binding, binding->scope, target);
+ run(binding->index, context, binding, binding->scope, target, flags);
- vt->write(binding->target, binding->property & 0xFFFF,
- QDeclarativePropertyPrivate::DontRemoveBinding);
+ vt->write(binding->target, binding->property & 0xFFFF, flags);
} else {
- run(binding->index, context, binding, binding->scope, binding->target);
+ run(binding->index, context, binding, binding->scope, binding->target, flags);
}
binding->updating = false;
}
@@ -334,6 +334,7 @@ namespace {
struct Instr {
enum {
Noop,
+ BindingId, // id
Subscribe, // subscribe
SubscribeId, // subscribe
@@ -404,6 +405,12 @@ struct Instr {
} common;
struct {
quint8 type;
+ quint8 packing;
+ quint16 column;
+ quint32 line;
+ } id;
+ struct {
+ quint8 type;
quint8 packing[3];
quint16 subscriptions;
quint16 identifiers;
@@ -943,156 +950,158 @@ static void dumpInstruction(const Instr *instr)
{
switch (instr->common.type) {
case Instr::Noop:
- qWarning().nospace() << "Noop";
+ qWarning().nospace() << "\t" << "Noop";
+ break;
+ case Instr::BindingId:
+ qWarning().nospace() << instr->id.line << ":" << instr->id.column << ":";
break;
case Instr::Subscribe:
- qWarning().nospace() << "Subscribe" << "\t\t" << instr->subscribe.offset << "\t" << instr->subscribe.reg << "\t" << instr->subscribe.index;
+ qWarning().nospace() << "\t" << "Subscribe" << "\t\t" << instr->subscribe.offset << "\t" << instr->subscribe.reg << "\t" << instr->subscribe.index;
break;
case Instr::SubscribeId:
- qWarning().nospace() << "SubscribeId" << "\t\t" << instr->subscribe.offset << "\t" << instr->subscribe.reg << "\t" << instr->subscribe.index;
+ qWarning().nospace() << "\t" << "SubscribeId" << "\t\t" << instr->subscribe.offset << "\t" << instr->subscribe.reg << "\t" << instr->subscribe.index;
break;
case Instr::FetchAndSubscribe:
- qWarning().nospace() << "FetchAndSubscribe" << "\t" << instr->fetchAndSubscribe.output << "\t" << instr->fetchAndSubscribe.objectReg << "\t" << instr->fetchAndSubscribe.subscription;
+ qWarning().nospace() << "\t" << "FetchAndSubscribe" << "\t" << instr->fetchAndSubscribe.output << "\t" << instr->fetchAndSubscribe.objectReg << "\t" << instr->fetchAndSubscribe.subscription;
break;
case Instr::LoadId:
- qWarning().nospace() << "LoadId" << "\t\t\t" << instr->load.index << "\t" << instr->load.reg;
+ qWarning().nospace() << "\t" << "LoadId" << "\t\t\t" << instr->load.index << "\t" << instr->load.reg;
break;
case Instr::LoadScope:
- qWarning().nospace() << "LoadScope" << "\t\t" << instr->load.index << "\t" << instr->load.reg;
+ qWarning().nospace() << "\t" << "LoadScope" << "\t\t" << instr->load.index << "\t" << instr->load.reg;
break;
case Instr::LoadRoot:
- qWarning().nospace() << "LoadRoot" << "\t\t" << instr->load.index << "\t" << instr->load.reg;
+ qWarning().nospace() << "\t" << "LoadRoot" << "\t\t" << instr->load.index << "\t" << instr->load.reg;
break;
case Instr::LoadAttached:
- qWarning().nospace() << "LoadAttached" << "\t\t" << instr->attached.output << "\t" << instr->attached.reg << "\t" << instr->attached.index;
+ qWarning().nospace() << "\t" << "LoadAttached" << "\t\t" << instr->attached.output << "\t" << instr->attached.reg << "\t" << instr->attached.index;
break;
case Instr::ConvertIntToReal:
- qWarning().nospace() << "ConvertIntToReal" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
+ qWarning().nospace() << "\t" << "ConvertIntToReal" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
break;
case Instr::ConvertRealToInt:
- qWarning().nospace() << "ConvertRealToInt" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
+ qWarning().nospace() << "\t" << "ConvertRealToInt" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
break;
case Instr::Real:
- qWarning().nospace() << "Real" << "\t\t\t" << instr->real_value.reg << "\t" << instr->real_value.value;
+ qWarning().nospace() << "\t" << "Real" << "\t\t\t" << instr->real_value.reg << "\t" << instr->real_value.value;
break;
case Instr::Int:
- qWarning().nospace() << "Int" << "\t\t\t" << instr->int_value.reg << "\t" << instr->int_value.value;
+ qWarning().nospace() << "\t" << "Int" << "\t\t\t" << instr->int_value.reg << "\t" << instr->int_value.value;
break;
case Instr::Bool:
- qWarning().nospace() << "Bool" << "\t\t\t" << instr->bool_value.reg << "\t" << instr->bool_value.value;
+ qWarning().nospace() << "\t" << "Bool" << "\t\t\t" << instr->bool_value.reg << "\t" << instr->bool_value.value;
break;
case Instr::String:
- qWarning().nospace() << "String" << "\t\t\t" << instr->string_value.reg << "\t" << instr->string_value.offset << "\t" << instr->string_value.length;
+ qWarning().nospace() << "\t" << "String" << "\t\t\t" << instr->string_value.reg << "\t" << instr->string_value.offset << "\t" << instr->string_value.length;
break;
case Instr::AddReal:
- qWarning().nospace() << "AddReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "AddReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::AddInt:
- qWarning().nospace() << "AddInt" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "AddInt" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::AddString:
- qWarning().nospace() << "AddString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "AddString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::MinusReal:
- qWarning().nospace() << "MinusReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "MinusReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::MinusInt:
- qWarning().nospace() << "MinusInt" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "MinusInt" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::CompareReal:
- qWarning().nospace() << "CompareReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "CompareReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::CompareString:
- qWarning().nospace() << "CompareString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "CompareString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::NotCompareReal:
- qWarning().nospace() << "NotCompareReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "NotCompareReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::NotCompareString:
- qWarning().nospace() << "NotCompareString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "NotCompareString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::GreaterThanReal:
- qWarning().nospace() << "GreaterThanReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "GreaterThanReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::MaxReal:
- qWarning().nospace() << "MaxReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "MaxReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::MinReal:
- qWarning().nospace() << "MinReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ qWarning().nospace() << "\t" << "MinReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::NewString:
- qWarning().nospace() << "NewString" << "\t\t" << instr->construct.reg;
+ qWarning().nospace() << "\t" << "NewString" << "\t\t" << instr->construct.reg;
break;
case Instr::NewUrl:
- qWarning().nospace() << "NewUrl" << "\t\t\t" << instr->construct.reg;
+ qWarning().nospace() << "\t" << "NewUrl" << "\t\t\t" << instr->construct.reg;
break;
case Instr::CleanupString:
- qWarning().nospace() << "CleanupString" << "\t\t" << instr->cleanup.reg;
+ qWarning().nospace() << "\t" << "CleanupString" << "\t\t" << instr->cleanup.reg;
break;
case Instr::CleanupUrl:
- qWarning().nospace() << "CleanupUrl" << "\t\t" << instr->cleanup.reg;
+ qWarning().nospace() << "\t" << "CleanupUrl" << "\t\t" << instr->cleanup.reg;
break;
case Instr::Fetch:
- qWarning().nospace() << "Fetch" << "\t\t\t" << instr->fetch.output << "\t" << instr->fetch.index << "\t" << instr->fetch.objectReg;
+ qWarning().nospace() << "\t" << "Fetch" << "\t\t\t" << instr->fetch.output << "\t" << instr->fetch.index << "\t" << instr->fetch.objectReg;
break;
case Instr::Store:
- qWarning().nospace() << "Store" << "\t\t\t" << instr->store.output << "\t" << instr->store.index << "\t" << instr->store.reg;
+ qWarning().nospace() << "\t" << "Store" << "\t\t\t" << instr->store.output << "\t" << instr->store.index << "\t" << instr->store.reg;
break;
case Instr::Copy:
- qWarning().nospace() << "Copy" << "\t\t\t" << instr->copy.reg << "\t" << instr->copy.src;
+ qWarning().nospace() << "\t" << "Copy" << "\t\t\t" << instr->copy.reg << "\t" << instr->copy.src;
break;
case Instr::Skip:
- qWarning().nospace() << "Skip" << "\t\t\t" << instr->skip.reg << "\t" << instr->skip.count;
+ qWarning().nospace() << "\t" << "Skip" << "\t\t\t" << instr->skip.reg << "\t" << instr->skip.count;
break;
case Instr::Done:
- qWarning().nospace() << "Done";
+ qWarning().nospace() << "\t" << "Done";
break;
case Instr::InitString:
- qWarning().nospace() << "InitString" << "\t\t" << instr->initstring.offset << "\t" << instr->initstring.dataIdx;
+ qWarning().nospace() << "\t" << "InitString" << "\t\t" << instr->initstring.offset << "\t" << instr->initstring.dataIdx;
break;
case Instr::FindGeneric:
- qWarning().nospace() << "FindGeneric" << "\t\t" << instr->find.reg << "\t" << instr->find.name;
+ qWarning().nospace() << "\t" << "FindGeneric" << "\t\t" << instr->find.reg << "\t" << instr->find.name;
break;
case Instr::FindGenericTerminal:
- qWarning().nospace() << "FindGenericTerminal" << "\t" << instr->find.reg << "\t" << instr->find.name;
+ qWarning().nospace() << "\t" << "FindGenericTerminal" << "\t" << instr->find.reg << "\t" << instr->find.name;
break;
case Instr::FindProperty:
- qWarning().nospace() << "FindProperty" << "\t\t" << instr->find.reg << "\t" << instr->find.src << "\t" << instr->find.name;
+ qWarning().nospace() << "\t" << "FindProperty" << "\t\t" << instr->find.reg << "\t" << instr->find.src << "\t" << instr->find.name;
break;
case Instr::FindPropertyTerminal:
- qWarning().nospace() << "FindPropertyTerminal" << "\t" << instr->find.reg << "\t" << instr->find.src << "\t" << instr->find.name;
+ qWarning().nospace() << "\t" << "FindPropertyTerminal" << "\t" << instr->find.reg << "\t" << instr->find.src << "\t" << instr->find.name;
break;
case Instr::CleanupGeneric:
- qWarning().nospace() << "CleanupGeneric" << "\t\t" << instr->cleanup.reg;
+ qWarning().nospace() << "\t" << "CleanupGeneric" << "\t\t" << instr->cleanup.reg;
break;
case Instr::ConvertGenericToReal:
- qWarning().nospace() << "ConvertGenericToReal" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
+ qWarning().nospace() << "\t" << "ConvertGenericToReal" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
break;
case Instr::ConvertGenericToBool:
- qWarning().nospace() << "ConvertGenericToBool" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
+ qWarning().nospace() << "\t" << "ConvertGenericToBool" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
break;
case Instr::ConvertGenericToString:
- qWarning().nospace() << "ConvertGenericToString" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
+ qWarning().nospace() << "\t" << "ConvertGenericToString" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
break;
case Instr::ConvertGenericToUrl:
- qWarning().nospace() << "ConvertGenericToUrl" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
+ qWarning().nospace() << "\t" << "ConvertGenericToUrl" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
break;
default:
- qWarning().nospace() << "Unknown";
+ qWarning().nospace() << "\t" << "Unknown";
break;
}
}
void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
QDeclarativeContextData *context, QDeclarativeDelayedError *error,
- QObject *scope, QObject *output)
+ QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags)
{
Q_Q(QDeclarativeCompiledBindings);
error->removeError();
Register registers[32];
- int storeFlags = 0;
QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(context->engine);
Program *program = (Program *)programData;
@@ -1112,6 +1121,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
switch (instr->common.type) {
case Instr::Noop:
+ case Instr::BindingId:
break;
case Instr::SubscribeId:
@@ -1595,6 +1605,17 @@ bool QDeclarativeBindingCompilerPrivate::compile(QDeclarativeJS::AST::Node *node
if (destination->type == -1)
return false;
+ if (bindingsDump()) {
+ QDeclarativeJS::AST::ExpressionNode *n = node->expressionCast();
+ if (n) {
+ Instr id;
+ id.common.type = Instr::BindingId;
+ id.id.column = n->firstSourceLocation().startColumn;
+ id.id.line = n->firstSourceLocation().startLine;
+ bytecode << id;
+ }
+ }
+
Result type;
if (!parseExpression(node, type))
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index f4ccce1..fad7779 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -146,7 +146,7 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
For example:
\code
- COMPILE_EXCEPTION(property, QCoreApplication::translate("QDeclarativeCompiler","Error for property \"%1\"").arg(QString::fromUtf8(property->name)));
+ COMPILE_EXCEPTION(property, tr("Error for property \"%1\"").arg(QString::fromUtf8(property->name)));
\endcode
*/
#define COMPILE_EXCEPTION(token, desc) \
@@ -184,7 +184,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
QString string = v->value.asScript();
if (!prop.isWritable())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
if (prop.isEnumType()) {
int value;
@@ -193,7 +193,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
} else
value = prop.enumerator().keyToValue(string.toUtf8().constData());
if (value == -1)
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: unknown enumeration"));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: unknown enumeration"));
return true;
}
int type = prop.userType();
@@ -201,65 +201,65 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case -1:
break;
case QVariant::String:
- if (!v->value.isString()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: string expected"));
+ if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected"));
break;
case QVariant::Url:
- if (!v->value.isString()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: url expected"));
+ if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: url expected"));
break;
case QVariant::UInt:
{
bool ok;
string.toUInt(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: unsigned int expected"));
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsigned int expected"));
}
break;
case QVariant::Int:
{
bool ok;
string.toInt(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: int expected"));
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int expected"));
}
break;
case QMetaType::Float:
{
bool ok;
string.toFloat(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: float expected"));
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: float expected"));
}
break;
case QVariant::Double:
{
bool ok;
string.toDouble(&ok);
- if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: double expected"));
+ if (!v->value.isNumber() || !ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: double expected"));
}
break;
case QVariant::Color:
{
bool ok;
QDeclarativeStringConverters::colorFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: color expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
}
break;
case QVariant::Date:
{
bool ok;
QDeclarativeStringConverters::dateFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: date expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected"));
}
break;
case QVariant::Time:
{
bool ok;
QDeclarativeStringConverters::timeFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: time expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: time expected"));
}
break;
case QVariant::DateTime:
{
bool ok;
QDeclarativeStringConverters::dateTimeFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: datetime expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
}
break;
case QVariant::Point:
@@ -267,7 +267,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
{
bool ok;
QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: point expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: point expected"));
}
break;
case QVariant::Size:
@@ -275,7 +275,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
{
bool ok;
QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: size expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: size expected"));
}
break;
case QVariant::Rect:
@@ -283,19 +283,19 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
{
bool ok;
QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: rect expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: rect expected"));
}
break;
case QVariant::Bool:
{
- if (!v->value.isBoolean()) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: boolean expected"));
+ if (!v->value.isBoolean()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: boolean expected"));
}
break;
case QVariant::Vector3D:
{
bool ok;
QDeclarativeStringConverters::vector3DFromString(string, &ok);
- if (!ok) COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: 3D vector expected"));
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 3D vector expected"));
}
break;
default:
@@ -304,7 +304,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
QDeclarativeMetaType::StringConverter converter =
QDeclarativeMetaType::customStringConverter(t);
if (!converter)
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName(prop.type()))));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName(prop.type()))));
}
break;
}
@@ -342,9 +342,22 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
switch(type) {
case -1:
{
- instr.type = QDeclarativeInstruction::StoreVariant;
- instr.storeString.propertyIndex = prop.propertyIndex();
- instr.storeString.value = output->indexForString(string);
+ if (v->value.isNumber()) {
+ double n = v->value.asNumber();
+ if (double(int(n)) == n) {
+ instr.type = QDeclarativeInstruction::StoreVariantInteger;
+ instr.storeInteger.propertyIndex = prop.propertyIndex();
+ instr.storeInteger.value = int(n);
+ } else {
+ instr.type = QDeclarativeInstruction::StoreVariantDouble;
+ instr.storeDouble.propertyIndex = prop.propertyIndex();
+ instr.storeDouble.value = n;
+ }
+ } else {
+ instr.type = QDeclarativeInstruction::StoreVariant;
+ instr.storeString.propertyIndex = prop.propertyIndex();
+ instr.storeString.value = output->indexForString(string);
+ }
}
break;
case QVariant::String:
@@ -560,7 +573,7 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
if (tref.type) {
ref.type = tref.type;
if (!ref.type->isCreatable())
- COMPILE_EXCEPTION(parserRef->refObjects.first(), QCoreApplication::translate("QDeclarativeCompiler", "Element is not creatable."));
+ COMPILE_EXCEPTION(parserRef->refObjects.first(), tr( "Element is not creatable."));
} else if (tref.unit) {
ref.component = tref.unit->toComponent(engine);
@@ -881,23 +894,38 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
}
// Create the object
- QDeclarativeInstruction create;
- create.type = QDeclarativeInstruction::CreateObject;
- create.line = obj->location.start.line;
- create.create.column = obj->location.start.column;
- create.create.data = -1;
- if (!obj->custom.isEmpty())
- create.create.data = output->indexForByteArray(obj->custom);
- create.create.type = obj->type;
- if (!output->types.at(create.create.type).type &&
- !obj->bindingBitmask.isEmpty()) {
- Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
- create.create.bindingBits =
- output->indexForByteArray(obj->bindingBitmask);
+ if (obj->custom.isEmpty() && output->types.at(obj->type).type &&
+ !output->types.at(obj->type).type->isExtendedType() && obj != compileState.root) {
+
+ QDeclarativeInstruction create;
+ create.type = QDeclarativeInstruction::CreateSimpleObject;
+ create.line = obj->location.start.line;
+ create.createSimple.create = output->types.at(obj->type).type->createFunction();
+ create.createSimple.typeSize = output->types.at(obj->type).type->createSize();
+ create.createSimple.column = obj->location.start.column;
+ output->bytecode << create;
+
} else {
- create.create.bindingBits = -1;
+
+ QDeclarativeInstruction create;
+ create.type = QDeclarativeInstruction::CreateObject;
+ create.line = obj->location.start.line;
+ create.create.column = obj->location.start.column;
+ create.create.data = -1;
+ if (!obj->custom.isEmpty())
+ create.create.data = output->indexForByteArray(obj->custom);
+ create.create.type = obj->type;
+ if (!output->types.at(create.create.type).type &&
+ !obj->bindingBitmask.isEmpty()) {
+ Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
+ create.create.bindingBits =
+ output->indexForByteArray(obj->bindingBitmask);
+ } else {
+ create.create.bindingBits = -1;
+ }
+ output->bytecode << create;
+
}
- output->bytecode << create;
// Setup the synthesized meta object if necessary
if (!obj->metadata.isEmpty()) {
@@ -1148,23 +1176,23 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
Property *idProp = 0;
if (obj->properties.count() > 1 ||
(obj->properties.count() == 1 && obj->properties.begin().key() != "id"))
- COMPILE_EXCEPTION(*obj->properties.begin(), QCoreApplication::translate("QDeclarativeCompiler","Component elements may not contain properties other than id"));
+ COMPILE_EXCEPTION(*obj->properties.begin(), tr("Component elements may not contain properties other than id"));
if (!obj->scriptBlockObjects.isEmpty())
- COMPILE_EXCEPTION(obj->scriptBlockObjects.first(), QCoreApplication::translate("QDeclarativeCompiler","Component elements may not contain script blocks"));
+ COMPILE_EXCEPTION(obj->scriptBlockObjects.first(), tr("Component elements may not contain script blocks"));
if (obj->properties.count())
idProp = *obj->properties.begin();
if (idProp) {
if (idProp->value || idProp->values.count() > 1 || idProp->values.at(0)->object)
- COMPILE_EXCEPTION(idProp, QCoreApplication::translate("QDeclarativeCompiler","Invalid component id specification"));
+ COMPILE_EXCEPTION(idProp, tr("Invalid component id specification"));
COMPILE_CHECK(checkValidId(idProp->values.first(), idProp->values.first()->primitive()));
QString idVal = idProp->values.first()->primitive();
if (compileState.ids.contains(idVal))
- COMPILE_EXCEPTION(idProp, QCoreApplication::translate("QDeclarativeCompiler","id is not unique"));
+ COMPILE_EXCEPTION(idProp, tr("id is not unique"));
obj->id = idVal;
addId(idVal, obj);
@@ -1174,14 +1202,14 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
if (obj->defaultProperty &&
(obj->defaultProperty->value || obj->defaultProperty->values.count() > 1 ||
(obj->defaultProperty->values.count() == 1 && !obj->defaultProperty->values.first()->object)))
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Invalid component body specification"));
+ COMPILE_EXCEPTION(obj, tr("Invalid component body specification"));
Object *root = 0;
if (obj->defaultProperty && obj->defaultProperty->values.count())
root = obj->defaultProperty->values.first()->object;
if (!root)
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Cannot create empty component specification"));
+ COMPILE_EXCEPTION(obj, tr("Cannot create empty component specification"));
// Build the component tree
COMPILE_CHECK(buildComponentFromRoot(root, ctxt));
@@ -1200,11 +1228,11 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara
Property *source = *script->properties.begin();
if (script->defaultProperty)
- COMPILE_EXCEPTION(source, QCoreApplication::translate("QDeclarativeCompiler","Invalid Script block. Specify either the source property or inline script"));
+ COMPILE_EXCEPTION(source, tr("Invalid Script block. Specify either the source property or inline script"));
if (source->value || source->values.count() != 1 ||
source->values.at(0)->object || !source->values.at(0)->value.isStringList())
- COMPILE_EXCEPTION(source, QCoreApplication::translate("QDeclarativeCompiler","Invalid Script source value"));
+ COMPILE_EXCEPTION(source, tr("Invalid Script source value"));
QStringList sources = source->values.at(0)->value.asStringList();
@@ -1229,7 +1257,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara
}
} else if (!script->properties.isEmpty()) {
- COMPILE_EXCEPTION(*script->properties.begin(), QCoreApplication::translate("QDeclarativeCompiler","Properties cannot be set on Script block"));
+ COMPILE_EXCEPTION(*script->properties.begin(), tr("Properties cannot be set on Script block"));
} else if (script->defaultProperty) {
QString scriptCode;
@@ -1243,7 +1271,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara
if (lineNumber == 1)
lineNumber = v->location.start.line;
if (v->object || !v->value.isString())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid Script block"));
+ COMPILE_EXCEPTION(v, tr("Invalid Script block"));
if (ii == 0) {
currentLocation = v->location.start;
@@ -1387,7 +1415,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
} else {
if (prop->value || prop->values.count() != 1)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Incorrectly specified signal assignment"));
+ COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment"));
prop->index = sigIdx;
obj->addSignalProperty(prop);
@@ -1400,7 +1428,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
QString script = prop->values.at(0)->value.asScript().trimmed();
if (script.isEmpty())
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Empty signal assignment"));
+ COMPILE_EXCEPTION(prop, tr("Empty signal assignment"));
compileState.signalExpressions.insert(prop->values.at(0), ctxt);
}
@@ -1438,7 +1466,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
const BindingContext &ctxt)
{
if (prop->isEmpty())
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Empty property assignment"));
+ COMPILE_EXCEPTION(prop, tr("Empty property assignment"));
const QMetaObject *metaObject = obj->metaObject();
Q_ASSERT(metaObject);
@@ -1450,7 +1478,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
// Attached properties cannot be used on sub-objects. Sub-objects
// always exist in a binding sub-context, which is what we test
// for here.
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Attached properties cannot be used here"));
+ COMPILE_EXCEPTION(prop, tr("Attached properties cannot be used here"));
}
QDeclarativeType *type = 0;
@@ -1465,11 +1493,11 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
ctxt));
return true;
} else if (!type || !type->attachedPropertiesType()) {
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Non-existent attached object"));
+ COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
}
if (!prop->value)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Invalid attached object assignment"));
+ COMPILE_EXCEPTION(prop, tr("Invalid attached object assignment"));
Q_ASSERT(type->attachedPropertiesFunction());
prop->index = type->index();
@@ -1522,9 +1550,9 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
} else if (prop->index == -1) {
if (prop->isDefault) {
- COMPILE_EXCEPTION(prop->values.first(), QCoreApplication::translate("QDeclarativeCompiler","Cannot assign to non-existent default property"));
+ COMPILE_EXCEPTION(prop->values.first(), tr("Cannot assign to non-existent default property"));
} else {
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
}
} else if (prop->value) {
@@ -1555,12 +1583,12 @@ QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeEnginePrivate::Import
const BindingContext &ctxt)
{
if (!nsProp->value)
- COMPILE_EXCEPTION(nsProp, QCoreApplication::translate("QDeclarativeCompiler","Invalid use of namespace"));
+ COMPILE_EXCEPTION(nsProp, tr("Invalid use of namespace"));
foreach (Property *prop, nsProp->value->properties) {
if (!isAttachedPropertyName(prop->name))
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Not an attached property name"));
+ COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
// Setup attached property data
@@ -1569,10 +1597,10 @@ QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeEnginePrivate::Import
&type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Non-existent attached object"));
+ COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
if (!prop->value)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Invalid attached object assignment"));
+ COMPILE_EXCEPTION(prop, tr("Invalid attached object assignment"));
Q_ASSERT(type->attachedPropertiesFunction());
prop->index = type->index();
@@ -1743,7 +1771,7 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
if (prop->value ||
prop->values.count() > 1 ||
prop->values.at(0)->object)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Invalid use of id property"));
+ COMPILE_EXCEPTION(prop, tr("Invalid use of id property"));
QDeclarativeParser::Value *idValue = prop->values.at(0);
QString val = idValue->primitive();
@@ -1751,7 +1779,7 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
COMPILE_CHECK(checkValidId(idValue, val));
if (compileState.ids.contains(val))
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","id is not unique"));
+ COMPILE_EXCEPTION(prop, tr("id is not unique"));
prop->values.at(0)->type = Value::Id;
@@ -1832,17 +1860,21 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
if (prop->values.count()) {
if (prop->values.at(0)->location < prop->value->location) {
- COMPILE_EXCEPTION(prop->value, QCoreApplication::translate("QDeclarativeCompiler", "Property has already been assigned a value"));
+ COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value"));
} else {
- COMPILE_EXCEPTION(prop->values.at(0), QCoreApplication::translate("QDeclarativeCompiler", "Property has already been assigned a value"));
+ COMPILE_EXCEPTION(prop->values.at(0), tr( "Property has already been assigned a value"));
}
}
+ if (!obj->metaObject()->property(prop->index).isWritable()) {
+ COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ }
+
COMPILE_CHECK(buildValueTypeProperty(ep->valueTypes[prop->type],
prop->value, obj, ctxt.incr()));
obj->addValueTypeProperty(prop);
} else {
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Invalid grouped property access"));
+ COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
}
} else {
@@ -1850,10 +1882,10 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
prop->value->metatype =
QDeclarativeEnginePrivate::get(engine)->metaObjectForType(prop->type);
if (!prop->value->metatype)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Invalid grouped property access"));
+ COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
if (prop->values.count())
- COMPILE_EXCEPTION(prop->values.at(0), QCoreApplication::translate("QDeclarativeCompiler", "Cannot assign a value directly to a grouped property"));
+ COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign a value directly to a grouped property"));
obj->addGroupedProperty(prop);
@@ -1869,28 +1901,28 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
const BindingContext &ctxt)
{
if (obj->defaultProperty)
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Invalid property use"));
+ COMPILE_EXCEPTION(obj, tr("Invalid property use"));
obj->metatype = type->metaObject();
foreach (Property *prop, obj->properties) {
int idx = type->metaObject()->indexOfProperty(prop->name.constData());
if (idx == -1)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
QMetaProperty p = type->metaObject()->property(idx);
prop->index = idx;
prop->type = p.userType();
prop->isValueTypeSubProperty = true;
if (prop->value)
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Property assignment expected"));
+ COMPILE_EXCEPTION(prop, tr("Property assignment expected"));
if (prop->values.count() > 1) {
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Single property assignment expected"));
+ COMPILE_EXCEPTION(prop, tr("Single property assignment expected"));
} else if (prop->values.count()) {
Value *value = prop->values.at(0);
if (value->object) {
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Unexpected object assignment"));
+ COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
} else if (value->value.isScript()) {
// ### Check for writability
BindingReference reference;
@@ -1947,19 +1979,19 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
// at runtime.
if (!listTypeIsInterface) {
if (!canCoerce(listType, v->object)) {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Cannot assign object to list"));
+ COMPILE_EXCEPTION(v, tr("Cannot assign object to list"));
}
}
} else if (v->value.isScript()) {
if (assignedBinding)
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Can only assign one binding to lists"));
+ COMPILE_EXCEPTION(v, tr("Can only assign one binding to lists"));
assignedBinding = true;
COMPILE_CHECK(buildBinding(v, prop, ctxt));
v->type = Value::PropertyBinding;
} else {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Cannot assign primitives to lists"));
+ COMPILE_EXCEPTION(v, tr("Cannot assign primitives to lists"));
}
}
@@ -1972,10 +2004,10 @@ bool QDeclarativeCompiler::buildScriptStringProperty(QDeclarativeParser::Propert
const BindingContext &ctxt)
{
if (prop->values.count() > 1)
- COMPILE_EXCEPTION(prop->values.at(1), QCoreApplication::translate("QDeclarativeCompiler", "Cannot assign multiple values to a script property"));
+ COMPILE_EXCEPTION(prop->values.at(1), tr( "Cannot assign multiple values to a script property"));
if (prop->values.at(0)->object || !prop->values.at(0)->value.isScript())
- COMPILE_EXCEPTION(prop->values.at(0), QCoreApplication::translate("QDeclarativeCompiler", "Invalid property assignment: script expected"));
+ COMPILE_EXCEPTION(prop->values.at(0), tr( "Invalid property assignment: script expected"));
obj->addScriptStringProperty(prop, ctxt.stack);
@@ -2022,7 +2054,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
Q_ASSERT(v->object->type != -1);
if (!obj->metaObject()->property(prop->index).isWritable())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
if (QDeclarativeMetaType::isInterface(prop->type)) {
@@ -2081,7 +2113,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
v->object = component;
COMPILE_CHECK(buildPropertyObjectAssignment(prop, obj, v, ctxt));
} else {
- COMPILE_EXCEPTION(v->object, QCoreApplication::translate("QDeclarativeCompiler","Cannot assign object to property"));
+ COMPILE_EXCEPTION(v->object, tr("Cannot assign object to property"));
}
}
@@ -2104,7 +2136,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert
Q_ASSERT(v->object->type != -1);
if (!obj->metaObject()->property(prop->index).isWritable())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
// Normally buildObject() will set this up, but we need the static
@@ -2131,7 +2163,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert
buildDynamicMeta(baseObj, ForceCreation);
v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
} else {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name.constData())));
+ COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name.constData())));
}
return true;
@@ -2179,7 +2211,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
return true;
if (!prop.isWritable())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
QString string = v->value.asString();
if (!string.at(0).isUpper())
@@ -2248,32 +2280,32 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
if (prop.isDefaultProperty) {
if (seenDefaultProperty)
- COMPILE_EXCEPTION(&prop, QCoreApplication::translate("QDeclarativeCompiler","Duplicate default property"));
+ COMPILE_EXCEPTION(&prop, tr("Duplicate default property"));
seenDefaultProperty = true;
}
if (propNames.contains(prop.name))
- COMPILE_EXCEPTION(&prop, QCoreApplication::translate("QDeclarativeCompiler","Duplicate property name"));
+ COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
if (QString::fromUtf8(prop.name).at(0).isUpper())
- COMPILE_EXCEPTION(&prop, QCoreApplication::translate("QDeclarativeCompiler","Property names cannot begin with an upper case letter"));
+ COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
propNames.insert(prop.name);
}
for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
QByteArray name = obj->dynamicSignals.at(ii).name;
if (methodNames.contains(name))
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Duplicate signal name"));
+ COMPILE_EXCEPTION(obj, tr("Duplicate signal name"));
if (QString::fromUtf8(name).at(0).isUpper())
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Signal names cannot begin with an upper case letter"));
+ COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
methodNames.insert(name);
}
for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
QByteArray name = obj->dynamicSlots.at(ii).name;
if (methodNames.contains(name))
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Duplicate method name"));
+ COMPILE_EXCEPTION(obj, tr("Duplicate method name"));
if (QString::fromUtf8(name).at(0).isUpper())
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","Method names cannot begin with an upper case letter"));
+ COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
methodNames.insert(name);
}
@@ -2294,11 +2326,11 @@ bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object
} else {
property = obj->getProperty(p.name);
if (!property->values.isEmpty())
- COMPILE_EXCEPTION(property, QCoreApplication::translate("QDeclarativeCompiler","Property value set multiple times"));
+ COMPILE_EXCEPTION(property, tr("Property value set multiple times"));
}
if (property->value)
- COMPILE_EXCEPTION(property, QCoreApplication::translate("QDeclarativeCompiler","Invalid property nesting"));
+ COMPILE_EXCEPTION(property, tr("Invalid property nesting"));
for (int ii = 0; ii < p.defaultValue->values.count(); ++ii) {
Value *v = p.defaultValue->values.at(ii);
@@ -2351,7 +2383,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
if (-1 != propIdx) {
QMetaProperty prop = obj->metaObject()->property(propIdx);
if (prop.isFinal())
- COMPILE_EXCEPTION(&p, QCoreApplication::translate("QDeclarativeCompiler","Cannot override FINAL property"));
+ COMPILE_EXCEPTION(&p, tr("Cannot override FINAL property"));
}
if (p.isDefaultProperty &&
@@ -2376,7 +2408,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine);
if (!priv->resolveType(unit->imports, p.customType, &qmltype,
&url, 0, 0, 0))
- COMPILE_EXCEPTION(&p, QCoreApplication::translate("QDeclarativeCompiler","Invalid property type"));
+ COMPILE_EXCEPTION(&p, tr("Invalid property type"));
if (!qmltype) {
QDeclarativeCompositeTypeData *tdata = priv->typeManager.get(url);
@@ -2505,7 +2537,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
((QDeclarativeVMEMetaData *)dynamicData.data())->methodCount++;
QDeclarativeVMEMetaData::MethodData methodData =
- { s.parameterNames.count(), 0, funcScript.length(), 0 };
+ { s.parameterNames.count(), 0, funcScript.length(), s.location.start.line };
dynamicData.append((char *)&methodData, sizeof(methodData));
}
@@ -2535,24 +2567,24 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
bool QDeclarativeCompiler::checkValidId(QDeclarativeParser::Value *v, const QString &val)
{
if (val.isEmpty())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler", "Invalid empty ID"));
+ COMPILE_EXCEPTION(v, tr( "Invalid empty ID"));
if (val.at(0).isLetter() && !val.at(0).isLower())
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler", "IDs cannot start with an uppercase letter"));
+ COMPILE_EXCEPTION(v, tr( "IDs cannot start with an uppercase letter"));
QChar u(QLatin1Char('_'));
for (int ii = 0; ii < val.count(); ++ii) {
if (ii == 0 && !val.at(ii).isLetter() && val.at(ii) != u) {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler", "IDs must start with a letter or underscore"));
+ COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
} else if (ii != 0 && !val.at(ii).isLetterOrNumber() && val.at(ii) != u) {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler", "IDs must contain only letters, numbers, and underscores"));
+ COMPILE_EXCEPTION(v, tr( "IDs must contain only letters, numbers, and underscores"));
}
}
if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(val))
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler", "ID illegally masks global JavaScript property"));
+ COMPILE_EXCEPTION(v, tr( "ID illegally masks global JavaScript property"));
return true;
}
@@ -2583,24 +2615,24 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
const Object::DynamicProperty &prop)
{
if (!prop.defaultValue)
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","No property alias location"));
+ COMPILE_EXCEPTION(obj, tr("No property alias location"));
if (prop.defaultValue->values.count() != 1 ||
prop.defaultValue->values.at(0)->object ||
!prop.defaultValue->values.at(0)->value.isScript())
- COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QDeclarativeCompiler","Invalid alias location"));
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
QDeclarativeJS::AST::Node *node = prop.defaultValue->values.at(0)->value.asAST();
if (!node)
- COMPILE_EXCEPTION(obj, QCoreApplication::translate("QDeclarativeCompiler","No property alias location")); // ### Can this happen?
+ COMPILE_EXCEPTION(obj, tr("No property alias location")); // ### Can this happen?
QStringList alias = astNodeToStringList(node);
if (alias.count() != 1 && alias.count() != 2)
- COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QDeclarativeCompiler","Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>"));
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>"));
if (!compileState.ids.contains(alias.at(0)))
- COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QDeclarativeCompiler","Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
Object *idObject = compileState.ids[alias.at(0)];
@@ -2613,7 +2645,7 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
if (-1 == propIdx)
- COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QDeclarativeCompiler","Invalid alias location"));
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
writable = aliasProperty.isWritable();
@@ -2667,7 +2699,7 @@ bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
if (!mp.isWritable() && !QDeclarativeMetaType::isList(prop->type))
- COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
BindingReference reference;
reference.expression = value->value;
@@ -2944,4 +2976,9 @@ QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object
return rv;
}
+QString QDeclarativeCompiler::tr(const char *str)
+{
+ return QCoreApplication::translate("QDeclarativeCompiler", str);
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 11364bb..0e47774 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -281,6 +281,8 @@ private:
void addId(const QString &, QDeclarativeParser::Object *);
+ QString tr(const char *);
+
void dumpStats();
struct BindingReference {
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
index 55723ea..05e8d22 100644
--- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp
+++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
@@ -55,13 +55,6 @@
QT_BEGIN_NAMESPACE
-#if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0))
-inline uint qHash(const QUrl &uri)
-{
- return qHash(uri.toEncoded(QUrl::FormattingOption(0x100)));
-}
-#endif
-
QDeclarativeCompositeTypeData::QDeclarativeCompositeTypeData()
: status(Invalid), errorType(NoError), component(0), compiledComponent(0)
{
@@ -633,10 +626,12 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData
// - type with unknown namespace (UnknownNamespace.SomeType {})
QDeclarativeError error;
error.setUrl(unit->imports.baseUrl());
+ QString userTypeName = QString::fromUtf8(typeName);
+ userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
if (typeNamespace)
- error.setDescription(tr("Namespace %1 cannot be used as a type").arg(QString::fromUtf8(typeName)));
+ error.setDescription(tr("Namespace %1 cannot be used as a type").arg(userTypeName));
else
- error.setDescription(tr("%1 is not a type").arg(QString::fromUtf8(typeName)));
+ error.setDescription(tr("%1 is not a type").arg(userTypeName));
if (!parserRef->refObjects.isEmpty()) {
QDeclarativeParser::Object *obj = parserRef->refObjects.first();
error.setLine(obj->location.start.line);
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 55c2f7c..9307bcc 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -623,6 +623,7 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object
if (iter == enginePriv->m_sharedScriptImports.end()) {
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
+ scriptContext->pushScope(enginePriv->contextClass->newContext(0, 0));
scriptContext->pushScope(enginePriv->globalClass->globalObject());
QScriptValue scope = scriptEngine->newObject();
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 6c5a1f7..eee72b6 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -174,7 +174,7 @@ public:
inline ContextGuard &operator=(QObject *obj)
{ QDeclarativeGuard<QObject>::operator=(obj); return *this; }
virtual void objectDestroyed(QObject *) {
- if (!QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify();
+ if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify();
}
QDeclarativeContextData *context;
QDeclarativeNotifier bindings;
diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
index 8566744..461fab5 100644
--- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
@@ -79,7 +79,7 @@ struct ContextData : public QScriptDeclarativeClass::Object {
via QtScript.
*/
QDeclarativeContextScriptClass::QDeclarativeContextScriptClass(QDeclarativeEngine *bindEngine)
-: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine),
+: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine),
lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1)
{
}
@@ -223,7 +223,7 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindConte
return 0;
}
-QDeclarativeContextScriptClass::ScriptValue
+QDeclarativeContextScriptClass::Value
QDeclarativeContextScriptClass::property(Object *object, const Identifier &name)
{
Q_UNUSED(object);
@@ -295,7 +295,7 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- ep->objectClass->setProperty(lastScopeObject, name, value, bindContext);
+ ep->objectClass->setProperty(lastScopeObject, name, value, context(), bindContext);
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontextscriptclass_p.h b/src/declarative/qml/qdeclarativecontextscriptclass_p.h
index b89f0cd..1936d38 100644
--- a/src/declarative/qml/qdeclarativecontextscriptclass_p.h
+++ b/src/declarative/qml/qdeclarativecontextscriptclass_p.h
@@ -54,14 +54,14 @@
//
#include "private/qdeclarativetypenamecache_p.h"
-#include "private/qdeclarativescriptclass_p.h"
+#include <private/qscriptdeclarativeclass_p.h>
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeContextData;
-class QDeclarativeContextScriptClass : public QDeclarativeScriptClass
+class QDeclarativeContextScriptClass : public QScriptDeclarativeClass
{
public:
QDeclarativeContextScriptClass(QDeclarativeEngine *);
@@ -76,7 +76,7 @@ public:
protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
QScriptClass::QueryFlags flags);
- virtual ScriptValue property(Object *, const Identifier &);
+ virtual Value property(Object *, const Identifier &);
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &);
private:
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index 8b6ee7c..1a97315 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -108,6 +108,9 @@ QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root
rootNode.d->properties << fromProperty(p);
}
+ if (root->defaultProperty)
+ rootNode.d->properties << fromProperty(root->defaultProperty);
+
return rootNode;
}
diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h
index adfff19..5b12629 100644
--- a/src/declarative/qml/qdeclarativedeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h
@@ -64,6 +64,10 @@ class QDeclarativeAbstractBinding;
class QDeclarativeContext;
class QDeclarativePropertyCache;
class QDeclarativeContextData;
+// This class is structured in such a way, that simply zero'ing it is the
+// default state for elemental object allocations. This is crucial in the
+// workings of the QDeclarativeInstruction::CreateSimpleObject instruction.
+// Don't change anything here without first considering that case!
class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData
{
public:
@@ -71,10 +75,20 @@ public:
: ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false),
context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0),
bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0),
- attachedProperties(0), propertyCache(0), guards(0) {}
+ attachedProperties(0), scriptValue(0), propertyCache(0), guards(0) {
+ init();
+ }
- virtual void destroyed(QObject *);
- virtual void parentChanged(QObject *, QObject *);
+ static inline void init() {
+ QDeclarativeData::destroyed = destroyed;
+ QDeclarativeData::parentChanged = parentChanged;
+ }
+
+ static void destroyed(QDeclarativeData *, QObject *);
+ static void parentChanged(QDeclarativeData *, QObject *, QObject *);
+
+ void destroyed(QObject *);
+ void parentChanged(QObject *, QObject *);
void setImplicitDestructible() {
if (!explicitIndestructibleSet) indestructible = false;
@@ -109,7 +123,9 @@ public:
QHash<int, QObject *> *attachedProperties;
- QScriptValue scriptValue;
+ // ### Can we make this QScriptValuePrivate so we incur no additional allocation
+ // cost?
+ QScriptValue *scriptValue;
QDeclarativePropertyCache *propertyCache;
QDeclarativeGuard<QObject> *guards;
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 52a1f45..f1adc16 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -61,7 +61,6 @@
#include "private/qdeclarativeglobal_p.h"
#include "private/qdeclarativeworkerscript_p.h"
#include "private/qdeclarativecomponent_p.h"
-#include "private/qdeclarativescriptclass_p.h"
#include "qdeclarativenetworkaccessmanagerfactory.h"
#include "qdeclarativeimageprovider.h"
#include "private/qdeclarativedirparser_p.h"
@@ -183,11 +182,11 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
fileImportPath.append(canonicalPath);
}
}
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
if (!builtinPath.isEmpty())
fileImportPath += builtinPath;
-#endif
+
+ filePluginPath += QLatin1String(".");
}
@@ -226,6 +225,7 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr
// XXX used to add Qt.Sound class.
//types
+ qtObject.setProperty(QLatin1String("isQtObject"), newFunction(QDeclarativeEnginePrivate::isQtObject, 1));
qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4));
qtObject.setProperty(QLatin1String("hsla"), newFunction(QDeclarativeEnginePrivate::hsla, 4));
qtObject.setProperty(QLatin1String("rect"), newFunction(QDeclarativeEnginePrivate::rect, 4));
@@ -346,6 +346,17 @@ Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer);
typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
+
+void QDeclarativeDeclarativeData::destroyed(QDeclarativeData *d, QObject *o)
+{
+ static_cast<QDeclarativeDeclarativeData *>(d)->destroyed(o);
+}
+
+void QDeclarativeDeclarativeData::parentChanged(QDeclarativeData *d, QObject *o, QObject *p)
+{
+ static_cast<QDeclarativeDeclarativeData *>(d)->parentChanged(o, p);
+}
+
void QDeclarativeEnginePrivate::init()
{
Q_Q(QDeclarativeEngine);
@@ -353,6 +364,8 @@ void QDeclarativeEnginePrivate::init()
qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
qRegisterMetaType<QScriptValue>("QScriptValue");
+ QDeclarativeDeclarativeData::init();
+
contextClass = new QDeclarativeContextScriptClass(q);
objectClass = new QDeclarativeObjectScriptClass(q);
valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
@@ -396,7 +409,7 @@ QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine
\code
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine);
- component.setData("import Qt 4.6\nText { text: \"Hello world!\" }", QUrl());
+ component.setData("import Qt 4.7\nText { text: \"Hello world!\" }", QUrl());
QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
//add item to view, etc
@@ -848,15 +861,16 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object)
if (ownContext)
context->destroy();
+ if (scriptValue)
+ delete scriptValue;
+
if (ownMemory)
delete this;
- else
- this->~QDeclarativeDeclarativeData();
}
void QDeclarativeDeclarativeData::parentChanged(QObject *, QObject *parent)
{
- if (!parent && scriptValue.isValid()) scriptValue = QScriptValue();
+ if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
}
bool QDeclarativeDeclarativeData::hasBindingBit(int bit) const
@@ -1014,6 +1028,14 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
}
+QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if (ctxt->argumentCount() == 0)
+ return QScriptValue(engine, false);
+
+ return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
+}
+
QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 3)
@@ -1310,7 +1332,6 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine
return qScriptValueFromValue(engine, qVariantFromValue(finalColor));
}
-
QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
{
if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
@@ -1321,6 +1342,14 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v
} else {
return scriptEngine.nullValue();
}
+ } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
+ const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
+ QScriptValue rv = scriptEngine.newArray(list.count());
+ for (int ii = 0; ii < list.count(); ++ii) {
+ QObject *object = list.at(ii);
+ rv.setProperty(ii, objectClass->newQObject(object));
+ }
+ return rv;
}
bool objOk;
@@ -1332,35 +1361,29 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v
}
}
-QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val)
+QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
{
QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
if (dc == objectClass)
return QVariant::fromValue(objectClass->toQObject(val));
+ else if (dc == valueTypeClass)
+ return valueTypeClass->toVariant(val);
else if (dc == contextClass)
return QVariant();
- QScriptDeclarativeClass *sc = QScriptDeclarativeClass::scriptClass(val);
- if (!sc) {
- return val.toVariant();
- } else if (sc == valueTypeClass) {
- return valueTypeClass->toVariant(val);
- } else {
- return QVariant();
+ // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
+ if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
+ QList<QObject *> list;
+ int length = val.property(QLatin1String("length")).toInt32();
+ for (int ii = 0; ii < length; ++ii) {
+ QScriptValue arrayItem = val.property(ii);
+ QObject *d = arrayItem.toQObject();
+ list << d;
+ }
+ return QVariant::fromValue(list);
}
-}
-QDeclarativeScriptClass::QDeclarativeScriptClass(QScriptEngine *engine)
-: QScriptDeclarativeClass(engine)
-{
-}
-
-QVariant QDeclarativeScriptClass::toVariant(QDeclarativeEngine *engine, const QScriptValue &val)
-{
- QDeclarativeEnginePrivate *ep =
- static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine));
-
- return ep->scriptValueToVariant(val);
+ return val.toVariant();
}
// XXX this beyonds in QUrl::toLocalFile()
@@ -1483,19 +1506,13 @@ public:
foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
- QDir pluginDir = dir.absoluteFilePath(plugin.path);
-
- // hack for resources, should probably go away
- if (absoluteFilePath.startsWith(QLatin1Char(':')))
- pluginDir = QDir(QCoreApplication::applicationDirPath());
-
QString resolvedFilePath =
QDeclarativeEnginePrivate::get(engine)
- ->resolvePlugin(pluginDir,
+ ->resolvePlugin(dir, plugin.path,
plugin.name);
if (!resolvedFilePath.isEmpty()) {
- engine->importExtension(resolvedFilePath, uri);
+ engine->importPlugin(resolvedFilePath, uri);
}
}
}
@@ -1619,6 +1636,18 @@ public:
url.chop(1);
}
+ if (vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
+ QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin();
+ for (; it != qmldircomponents.end(); ++it) {
+ if (it->majorVersion > vmaj || (it->majorVersion == vmaj && it->minorVersion >= vmin))
+ break;
+ }
+ if (it == qmldircomponents.end()) {
+ *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
+ return false;
+ }
+ }
+
s->uris.prepend(uri);
s->urls.prepend(url);
s->majversions.prepend(vmaj);
@@ -1778,8 +1807,8 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const
}
/*!
- Adds \a path as a directory where installed QML components are
- defined in a URL-based directory structure.
+ Adds \a path as a directory where the engine searches for
+ installed modules in a URL-based directory structure.
The newly added \a path will be first in the importPathList().
@@ -1802,7 +1831,7 @@ void QDeclarativeEngine::addImportPath(const QString& path)
/*!
Returns the list of directories where the engine searches for
- installed modules.
+ installed modules in a URL-based directory structure.
For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
@@ -1823,7 +1852,7 @@ QStringList QDeclarativeEngine::importPathList() const
/*!
Sets the list of directories where the engine searches for
- installed modules.
+ installed modules in a URL-based directory structure.
By default, the list contains the paths specified in the \c QML_IMPORT_PATH environment
variable, then the builtin \c ImportsPath from QLibraryInfo.
@@ -1836,15 +1865,73 @@ void QDeclarativeEngine::setImportPathList(const QStringList &paths)
d->fileImportPath = paths;
}
+
/*!
- Imports the extension named \a fileName from the \a uri provided.
- Returns true if the extension was successfully imported.
+ Adds \a path as a directory where the engine searches for
+ native plugins for imported modules (referenced in the \c qmldir file).
+
+ By default, the list contains only \c ., i.e. the engine searches
+ in the directory of the \c qmldir file itself.
+
+ The newly added \a path will be first in the pluginPathList().
+
+ \sa setPluginPathList()
*/
-bool QDeclarativeEngine::importExtension(const QString &fileName, const QString &uri)
+void QDeclarativeEngine::addPluginPath(const QString& path)
{
if (qmlImportTrace())
- qDebug() << "QDeclarativeEngine::importExtension" << uri << "from" << fileName;
- QFileInfo fileInfo(fileName);
+ qDebug() << "QDeclarativeEngine::addPluginPath" << path;
+ Q_D(QDeclarativeEngine);
+ QUrl url = QUrl(path);
+ if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) {
+ QDir dir = QDir(path);
+ d->filePluginPath.prepend(dir.canonicalPath());
+ } else {
+ d->filePluginPath.prepend(path);
+ }
+}
+
+
+/*!
+ Returns the list of directories where the engine searches for
+ native plugins for imported modules (referenced in the \c qmldir file).
+
+ By default, the list contains only \c ., i.e. the engine searches
+ in the directory of the \c qmldir file itself.
+
+ \sa addPluginPath() setPluginPathList()
+*/
+QStringList QDeclarativeEngine::pluginPathList() const
+{
+ Q_D(const QDeclarativeEngine);
+ return d->filePluginPath;
+}
+
+/*!
+ Sets the list of directories where the engine searches for
+ native plugins for imported modules (referenced in the \c qmldir file).
+
+ By default, the list contains only \c ., i.e. the engine searches
+ in the directory of the \c qmldir file itself.
+
+ \sa pluginPathList() addPluginPath()
+ */
+void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
+{
+ Q_D(QDeclarativeEngine);
+ d->filePluginPath = paths;
+}
+
+
+/*!
+ Imports the plugin named \a filePath with the \a uri provided.
+ Returns true if the plugin was successfully imported; otherwise returns false.
+*/
+bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri)
+{
+ if (qmlImportTrace())
+ qDebug() << "QDeclarativeEngine::importPlugin" << uri << "from" << filePath;
+ QFileInfo fileInfo(filePath);
const QString absoluteFilePath = fileInfo.absoluteFilePath();
QDeclarativeEnginePrivate *d = QDeclarativeEnginePrivate::get(this);
@@ -1860,6 +1947,13 @@ bool QDeclarativeEngine::importExtension(const QString &fileName, const QString
if (!engineInitialized || !typesRegistered) {
QPluginLoader loader(absoluteFilePath);
+ if (!loader.load()) {
+ if (qmlImportTrace()) {
+ qDebug() << "QDeclarativeEngine::importPlugin: " << loader.errorString();
+ }
+ return false;
+ }
+
if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) {
const QByteArray bytes = uri.toUtf8();
@@ -1878,6 +1972,8 @@ bool QDeclarativeEngine::importExtension(const QString &fileName, const QString
iface->initializeEngine(this, moduleId);
}
} else {
+ if (qmlImportTrace())
+ qDebug() << "QDeclarativeEngine::importPlugin: no DeclarativeExtensionInterface error";
return false;
}
}
@@ -1917,27 +2013,53 @@ QString QDeclarativeEngine::offlineStoragePath() const
/*!
\internal
- Returns the result of the merge of \a baseName with \a dir, \a suffixes, and \a prefix.
+ Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix.
The \a prefix must contain the dot.
+
+ \a qmldirPath is the location of the qmldir file.
*/
-QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString &baseName,
+QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName,
const QStringList &suffixes,
const QString &prefix)
{
- foreach (const QString &suffix, suffixes) {
- QString pluginFileName = prefix;
+ QStringList searchPaths = filePluginPath;
+ bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath);
+ if (!qmldirPluginPathIsRelative)
+ searchPaths.prepend(qmldirPluginPath);
+
+ foreach (const QString &pluginPath, searchPaths) {
+
+ QString resolvedPath;
+
+ if (pluginPath == QLatin1String(".")) {
+ if (qmldirPluginPathIsRelative)
+ resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
+ else
+ resolvedPath = qmldirPath.absolutePath();
+ } else {
+ resolvedPath = pluginPath;
+ }
+
+ // hack for resources, should probably go away
+ if (resolvedPath.startsWith(QLatin1Char(':')))
+ resolvedPath = QCoreApplication::applicationDirPath();
- pluginFileName += baseName;
- pluginFileName += suffix;
+ QDir dir(resolvedPath);
+ foreach (const QString &suffix, suffixes) {
+ QString pluginFileName = prefix;
- QFileInfo fileInfo(dir, pluginFileName);
+ pluginFileName += baseName;
+ pluginFileName += suffix;
- if (fileInfo.exists())
- return fileInfo.absoluteFilePath();
+ QFileInfo fileInfo(dir, pluginFileName);
+
+ if (fileInfo.exists())
+ return fileInfo.absoluteFilePath();
+ }
}
if (qmlImportTrace())
- qDebug() << "QDeclarativeEngine::resolvePlugin: Could not resolve plugin" << baseName << "in" << dir.absolutePath();
+ qDebug() << "QDeclarativeEngine::resolvePlugin: Could not resolve plugin" << baseName << "in" << qmldirPath.absolutePath();
return QString();
}
@@ -1958,17 +2080,17 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString
Version number on unix are ignored.
*/
-QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString &baseName)
+QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- return resolvePlugin(dir, baseName,
+ return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
<< QLatin1String("d.dll") // try a qmake-style debug build first
# endif
<< QLatin1String(".dll"));
#elif defined(Q_OS_SYMBIAN)
- return resolvePlugin(dir, baseName,
+ return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
QStringList()
<< QLatin1String(".dll")
<< QLatin1String(".qtplugin"));
@@ -1976,7 +2098,7 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString
# if defined(Q_OS_DARWIN)
- return resolvePlugin(dir, baseName,
+ return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
<< QLatin1String("_debug.dylib") // try a qmake-style debug build first
@@ -2010,7 +2132,7 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString
// Examples of valid library names:
// libfoo.so
- return resolvePlugin(dir, baseName, validSuffixList, QLatin1String("lib"));
+ return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
# endif
#endif
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index b861c1b..fcaddcf 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -81,7 +81,11 @@ public:
void setImportPathList(const QStringList &paths);
void addImportPath(const QString& dir);
- bool importExtension(const QString &fileName, const QString &uri);
+ QStringList pluginPathList() const;
+ void setPluginPathList(const QStringList &paths);
+ void addPluginPath(const QString& dir);
+
+ bool importPlugin(const QString &filePath, const QString &uri);
void setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *);
QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory() const;
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index 45089d0..7766ad6 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -231,6 +231,7 @@ public:
QDeclarativeCompositeTypeManager typeManager;
QStringList fileImportPath;
+ QStringList filePluginPath;
QString offlineStoragePath;
mutable quint32 uniqueId;
@@ -274,10 +275,10 @@ public:
QSet<QString> initializedPlugins;
- QString resolvePlugin(const QDir &dir, const QString &baseName,
+ QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName,
const QStringList &suffixes,
const QString &prefix = QString());
- QString resolvePlugin(const QDir &dir, const QString &baseName);
+ QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName);
bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork,
@@ -308,7 +309,7 @@ public:
QHash<QString, QScriptValue> m_sharedScriptImports;
QScriptValue scriptValueFromVariant(const QVariant &);
- QVariant scriptValueToVariant(const QScriptValue &);
+ QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid);
void sendQuit ();
@@ -316,6 +317,7 @@ public:
static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
static QScriptValue createQmlObject(QScriptContext*, QScriptEngine*);
+ static QScriptValue isQtObject(QScriptContext*, QScriptEngine*);
static QScriptValue vector(QScriptContext*, QScriptEngine*);
static QScriptValue rgba(QScriptContext*, QScriptEngine*);
static QScriptValue hsla(QScriptContext*, QScriptEngine*);
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index a250f21..2a3e557 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -175,7 +175,8 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *ex
}
QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
- const QString &program, QScriptValue *contextObject)
+ const QString &program, const QString &fileName,
+ int lineNumber, QScriptValue *contextObject)
{
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
@@ -186,7 +187,7 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex
scriptContext->pushScope(ep->contextClass->newContext(context, object));
}
scriptContext->pushScope(ep->globalClass->globalObject());
- QScriptValue rv = ep->scriptEngine.evaluate(program);
+ QScriptValue rv = ep->scriptEngine.evaluate(program, fileName, lineNumber);
ep->scriptEngine.popContext();
return rv;
}
@@ -351,7 +352,7 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine
}
}
-QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined)
+QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool *isUndefined)
{
QDeclarativeExpressionData *data = this->data;
QDeclarativeEngine *engine = data->context()->engine;
@@ -376,7 +377,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo
const QString code = rewriteBinding(data->expression, &ok);
if (!ok) {
scriptEngine->popContext();
- return QVariant();
+ return QScriptValue();
}
data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line);
}
@@ -413,54 +414,20 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo
if (scriptEngine->hasUncaughtException()) {
exceptionToError(scriptEngine, data->error);
scriptEngine->clearExceptions();
- return QVariant();
+ return QScriptValue();
} else {
data->error = QDeclarativeError();
+ return svalue;
}
-
- QVariant rv;
-
- if (svalue.isArray()) {
- int length = svalue.property(QLatin1String("length")).toInt32();
- if (length && svalue.property(0).isObject()) {
- QList<QObject *> list;
- for (int ii = 0; ii < length; ++ii) {
- QScriptValue arrayItem = svalue.property(ii);
- QObject *d = arrayItem.toQObject();
- list << d;
- }
- rv = QVariant::fromValue(list);
- }
- } else if (svalue.isObject() &&
- ep->objectClass->scriptClass(svalue) == ep->objectClass) {
- QObject *o = svalue.toQObject();
- int type = QMetaType::QObjectStar;
- // If the object is null, we extract the predicted type. While this isn't
- // 100% reliable, in many cases it gives us better error messages if we
- // assign this null-object to an incompatible property
- if (!o) type = ep->objectClass->objectType(svalue);
-
- return QVariant(type, &o);
- }
-
- if (rv.isNull())
- rv = svalue.toVariant();
-
- return rv;
}
-QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
+QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined)
{
Q_Q(QDeclarativeExpression);
-
- QVariant rv;
- if (!q->engine()) {
- qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context");
- return rv;
- }
+ Q_ASSERT(q->engine());
if (data->expression.isEmpty())
- return rv;
+ return QScriptValue();
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
@@ -476,7 +443,7 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU
QDeclarativeExpressionData *localData = data;
localData->addref();
- rv = evalQtScript(secondaryScope, isUndefined);
+ QScriptValue value = eval(secondaryScope, isUndefined);
ep->currentExpression = lastCurrentExpression;
ep->captureProperties = lastCaptureProperties;
@@ -494,7 +461,21 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU
lastCapturedProperties.copyAndClear(ep->capturedProperties);
- return rv;
+ return value;
+}
+
+QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
+{
+ Q_Q(QDeclarativeExpression);
+
+ if (!q->engine()) {
+ qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context");
+ return QVariant();
+ }
+
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
+
+ return ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined), qMetaTypeId<QList<QObject*> >());
}
/*!
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h
index 9a90fb6..d39aa2c 100644
--- a/src/declarative/qml/qdeclarativeexpression_p.h
+++ b/src/declarative/qml/qdeclarativeexpression_p.h
@@ -150,7 +150,9 @@ public:
QDeclarativeExpressionData *data;
QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
- QVariant evalQtScript(QObject *secondaryScope, bool *isUndefined = 0);
+ QScriptValue scriptValue(QObject *secondaryScope = 0, bool *isUndefined = 0);
+
+ QScriptValue eval(QObject *secondaryScope, bool *isUndefined = 0);
void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties);
void clearGuards();
@@ -165,8 +167,10 @@ public:
virtual void emitValueChanged();
static void exceptionToError(QScriptEngine *, QDeclarativeError &);
- static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, QScriptValue * = 0);
- static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, QScriptValue * = 0);
+ static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, const QString &,
+ int, QScriptValue *);
+ static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &,
+ QScriptValue *);
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp
index 3cf4d2b..d88d06a 100644
--- a/src/declarative/qml/qdeclarativeinstruction.cpp
+++ b/src/declarative/qml/qdeclarativeinstruction.cpp
@@ -60,6 +60,8 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
break;
case QDeclarativeInstruction::CreateObject:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className;
+ case QDeclarativeInstruction::CreateSimpleObject:
+ qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize;
break;
case QDeclarativeInstruction::SetId:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "SETID\t\t\t" << instr->setId.value << "\t\t\t" << primitives.at(instr->setId.value);
@@ -128,6 +130,12 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
case QDeclarativeInstruction::StoreVariant:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
break;
+ case QDeclarativeInstruction::StoreVariantInteger:
+ qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT_INTEGER\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value;
+ break;
+ case QDeclarativeInstruction::StoreVariantDouble:
+ qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT_DOUBLE\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value;
+ break;
case QDeclarativeInstruction::StoreObject:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_OBJECT\t\t" << instr->storeObject.propertyIndex;
break;
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index 877179d..e8287c0 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -74,6 +74,7 @@ public:
// top of the stack.
Init, /* init */
CreateObject, /* create */
+ CreateSimpleObject, /* createSimple */
SetId, /* setId */
SetDefault,
CreateComponent, /* createComponent */
@@ -113,6 +114,8 @@ public:
StoreRectF, /* storeRect */
StoreVector3D, /* storeVector3D */
StoreVariant, /* storeString */
+ StoreVariantInteger, /* storeInteger */
+ StoreVariantDouble, /* storeDouble */
StoreObject, /* storeObject */
StoreVariantObject, /* storeObject */
StoreInterface, /* storeObject */
@@ -175,6 +178,11 @@ public:
int bindingBits;
ushort column;
};
+ struct CreateSimpleInstruction {
+ void (*create)(void *);
+ int typeSize;
+ ushort column;
+ };
struct StoreMetaInstruction {
int data;
int aliasData;
@@ -305,6 +313,7 @@ public:
union {
InitInstruction init;
CreateInstruction create;
+ CreateSimpleInstruction createSimple;
StoreMetaInstruction storeMeta;
SetIdInstruction setId;
AssignValueSourceInstruction assignValueSource;
diff --git a/src/declarative/qml/qdeclarativelistscriptclass.cpp b/src/declarative/qml/qdeclarativelistscriptclass.cpp
index 3958dd5..d27427e 100644
--- a/src/declarative/qml/qdeclarativelistscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativelistscriptclass.cpp
@@ -54,7 +54,7 @@ struct ListData : public QScriptDeclarativeClass::Object {
};
QDeclarativeListScriptClass::QDeclarativeListScriptClass(QDeclarativeEngine *e)
-: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(e)), engine(e)
+: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(e)), engine(e)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
Q_UNUSED(scriptEngine);
@@ -114,7 +114,7 @@ QDeclarativeListScriptClass::queryProperty(Object *object, const Identifier &nam
}
}
-QDeclarativeListScriptClass::ScriptValue QDeclarativeListScriptClass::property(Object *obj, const Identifier &name)
+QDeclarativeListScriptClass::Value QDeclarativeListScriptClass::property(Object *obj, const Identifier &name)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
diff --git a/src/declarative/qml/qdeclarativelistscriptclass_p.h b/src/declarative/qml/qdeclarativelistscriptclass_p.h
index 68c680d..89984a1 100644
--- a/src/declarative/qml/qdeclarativelistscriptclass_p.h
+++ b/src/declarative/qml/qdeclarativelistscriptclass_p.h
@@ -53,13 +53,13 @@
// We mean it.
//
-#include <private/qdeclarativescriptclass_p.h>
+#include <private/qscriptdeclarativeclass_p.h>
#include "qdeclarativelist.h"
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
-class QDeclarativeListScriptClass : public QDeclarativeScriptClass
+class QDeclarativeListScriptClass : public QScriptDeclarativeClass
{
public:
QDeclarativeListScriptClass(QDeclarativeEngine *);
@@ -71,7 +71,7 @@ public:
protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
QScriptClass::QueryFlags flags);
- virtual ScriptValue property(Object *, const Identifier &);
+ virtual Value property(Object *, const Identifier &);
virtual QVariant toVariant(Object *, bool *ok);
private:
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index af21765..7b71608 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -313,11 +313,28 @@ QDeclarativeCustomParser *QDeclarativeType::customParser() const
return d->m_customParser;
}
+QDeclarativeType::CreateFunc QDeclarativeType::createFunction() const
+{
+ return d->m_newFunc;
+}
+
+int QDeclarativeType::createSize() const
+{
+ return d->m_allocationSize;
+}
+
bool QDeclarativeType::isCreatable() const
{
return d->m_newFunc != 0;
}
+bool QDeclarativeType::isExtendedType() const
+{
+ d->init();
+
+ return !d->m_metaObjects.isEmpty();
+}
+
bool QDeclarativeType::isInterface() const
{
return d->m_isInterface;
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index b3ec5e3..70b7c90 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -115,9 +115,14 @@ public:
QObject *create() const;
void create(QObject **, void **, size_t) const;
+ typedef void (*CreateFunc)(void *);
+ CreateFunc createFunction() const;
+ int createSize() const;
+
QDeclarativeCustomParser *customParser() const;
bool isCreatable() const;
+ bool isExtendedType() const;
bool isInterface() const;
int typeId() const;
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index d3ee67b..e1e33ab 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -52,6 +52,7 @@
#include <QtCore/qtimer.h>
#include <QtCore/qvarlengtharray.h>
+#include <QtScript/qscriptcontextinfo.h>
Q_DECLARE_METATYPE(QScriptValue);
@@ -78,11 +79,8 @@ struct ObjectData : public QScriptDeclarativeClass::Object {
QtScript for QML.
*/
QDeclarativeObjectScriptClass::QDeclarativeObjectScriptClass(QDeclarativeEngine *bindEngine)
-: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)),
-#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
- methods(bindEngine),
-#endif
- lastData(0), engine(bindEngine)
+: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)),
+ methods(bindEngine), lastData(0), engine(bindEngine)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -103,17 +101,20 @@ QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type
if (!object)
return newObject(scriptEngine, this, new ObjectData(object, type));
+ if (QObjectPrivate::get(object)->wasDeleted)
+ return scriptEngine->undefinedValue();
+
QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true);
if (!ddata) {
return scriptEngine->undefinedValue();
} else if (!ddata->indestructible && !object->parent()) {
return newObject(scriptEngine, this, new ObjectData(object, type));
- } else if (!ddata->scriptValue.isValid()) {
- ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type));
- return ddata->scriptValue;
- } else if (ddata->scriptValue.engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) {
- return ddata->scriptValue;
+ } else if (!ddata->scriptValue) {
+ ddata->scriptValue = new QScriptValue(newObject(scriptEngine, this, new ObjectData(object, type)));
+ return *ddata->scriptValue;
+ } else if (ddata->scriptValue->engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) {
+ return *ddata->scriptValue;
} else {
return newObject(scriptEngine, this, new ObjectData(object, type));
}
@@ -191,13 +192,13 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam
return 0;
}
-QDeclarativeObjectScriptClass::ScriptValue
+QDeclarativeObjectScriptClass::Value
QDeclarativeObjectScriptClass::property(Object *object, const Identifier &name)
{
return property(toQObject(object), name);
}
-QDeclarativeObjectScriptClass::ScriptValue
+QDeclarativeObjectScriptClass::Value
QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -225,15 +226,10 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name)
if (lastData->flags & QDeclarativePropertyCache::Data::IsVMEFunction) {
return Value(scriptEngine, ((QDeclarativeVMEMetaObject *)(obj->metaObject()))->vmeMethod(lastData->coreIndex));
} else {
-#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
// Uncomment to use QtScript method call logic
// QScriptValue sobj = scriptEngine->newQObject(obj);
// return Value(scriptEngine, sobj.property(toString(name)));
return Value(scriptEngine, methods.newMethod(obj, lastData));
-#else
- QScriptValue sobj = scriptEngine->newQObject(obj);
- return Value(scriptEngine, sobj.property(toString(name)));
-#endif
}
} else {
if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) {
@@ -298,7 +294,6 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name)
QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj);
return Value(scriptEngine, enginePriv->scriptValueFromVariant(var));
}
-
}
}
@@ -306,40 +301,41 @@ void QDeclarativeObjectScriptClass::setProperty(Object *object,
const Identifier &name,
const QScriptValue &value)
{
- return setProperty(toQObject(object), name, value);
+ return setProperty(toQObject(object), name, value, context());
}
void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
- const Identifier &name,
- const QScriptValue &value,
- QDeclarativeContextData *evalContext)
+ const Identifier &name,
+ const QScriptValue &value,
+ QScriptContext *context,
+ QDeclarativeContextData *evalContext)
{
Q_UNUSED(name);
Q_ASSERT(obj);
Q_ASSERT(lastData);
+ Q_ASSERT(context);
if (!lastData->isValid()) {
QString error = QLatin1String("Cannot assign to non-existent property \"") +
toString(name) + QLatin1Char('\"');
- if (context())
- context()->throwError(error);
+ context->throwError(error);
return;
}
- if (!(lastData->flags & QDeclarativePropertyCache::Data::IsWritable)) {
+ if (!(lastData->flags & QDeclarativePropertyCache::Data::IsWritable) &&
+ !(lastData->flags & QDeclarativePropertyCache::Data::IsQList)) {
QString error = QLatin1String("Cannot assign to read-only property \"") +
toString(name) + QLatin1Char('\"');
- if (context())
- context()->throwError(error);
+ context->throwError(error);
return;
}
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
- if (!evalContext && context()) {
+ if (!evalContext) {
// Global object, QScriptContext activation object, QDeclarativeContext object
- QScriptValue scopeNode = scopeChainValue(context(), -3);
+ QScriptValue scopeNode = scopeChainValue(context, -3);
if (scopeNode.isValid()) {
Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass);
@@ -355,10 +351,30 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
if (value.isUndefined() && lastData->flags & QDeclarativePropertyCache::Data::IsResettable) {
void *a[] = { 0 };
QMetaObject::metacall(obj, QMetaObject::ResetProperty, lastData->coreIndex, a);
+ } else if (value.isUndefined() && lastData->propType == qMetaTypeId<QVariant>()) {
+ QDeclarativePropertyPrivate::write(obj, *lastData, QVariant(), evalContext);
+ } else if (value.isUndefined()) {
+ QString error = QLatin1String("Cannot assign [undefined] to ") +
+ QLatin1String(QMetaType::typeName(lastData->propType));
+ context->throwError(error);
} else {
- // ### Can well known types be optimized?
- QVariant v = QDeclarativeScriptClass::toVariant(engine, value);
- QDeclarativePropertyPrivate::write(obj, *lastData, v, evalContext);
+ QVariant v;
+ if (lastData->flags & QDeclarativePropertyCache::Data::IsQList)
+ v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >());
+ else
+ v = enginePriv->scriptValueToVariant(value, lastData->propType);
+
+ if (!QDeclarativePropertyPrivate::write(obj, *lastData, v, evalContext)) {
+ const char *valueType = 0;
+ if (v.userType() == QVariant::Invalid) valueType = "null";
+ else valueType = QMetaType::typeName(v.userType());
+
+ QString error = QLatin1String("Cannot assign ") +
+ QLatin1String(valueType) +
+ QLatin1String(" to ") +
+ QLatin1String(QMetaType::typeName(lastData->propType));
+ context->throwError(error);
+ }
}
}
@@ -459,8 +475,6 @@ bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2)
return d1 == d2 || d1->object == d2->object;
}
-#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
-
struct MethodData : public QScriptDeclarativeClass::Object {
MethodData(QObject *o, const QDeclarativePropertyCache::Data &d) : object(o), data(d) {}
@@ -557,7 +571,7 @@ QDeclarativeObjectMethodScriptClass::queryProperty(Object *, const Identifier &n
}
-QDeclarativeObjectScriptClass::ScriptValue
+QDeclarativeObjectMethodScriptClass::Value
QDeclarativeObjectMethodScriptClass::property(Object *, const Identifier &name)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -687,16 +701,26 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
*((QObject **)&data) = value.toQObject();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
- new (&data) QVariant(QDeclarativeScriptClass::toVariant(engine, value));
+ new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value));
type = callType;
} else if (callType == qMetaTypeId<QList<QObject*> >()) {
- new (&data) QList<QObject *>(); // We don't support passing in QList<QObject*>
+ QList<QObject *> *list = new (&data) QList<QObject *>();
+ if (value.isArray()) {
+ int length = value.property(QLatin1String("length")).toInt32();
+ for (int ii = 0; ii < length; ++ii) {
+ QScriptValue arrayItem = value.property(ii);
+ QObject *d = arrayItem.toQObject();
+ list->append(d);
+ }
+ } else if (QObject *d = value.toQObject()) {
+ list->append(d);
+ }
type = callType;
} else {
new (&data) QVariant();
type = -1;
- QVariant v = QDeclarativeScriptClass::toVariant(engine, value);
+ QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
if (v.userType() == callType) {
*((QVariant *)&data) = v;
} else if (v.canConvert((QVariant::Type)callType)) {
@@ -803,7 +827,5 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass::
return Value();
}
-#endif
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
index 8941ae0..4b27e53 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
@@ -56,7 +56,7 @@
#include "private/qdeclarativepropertycache_p.h"
#include "private/qdeclarativetypenamecache_p.h"
-#include <private/qdeclarativescriptclass_p.h>
+#include <private/qscriptdeclarativeclass_p.h>
#include <QtScript/qscriptengine.h>
QT_BEGIN_NAMESPACE
@@ -66,7 +66,6 @@ class QScriptContext;
class QScriptEngine;
class QDeclarativeContextData;
-#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
class Q_AUTOTEST_EXPORT QDeclarativeObjectMethodScriptClass : public QScriptDeclarativeClass
{
public:
@@ -91,9 +90,8 @@ private:
QDeclarativeEngine *engine;
};
-#endif
-class Q_AUTOTEST_EXPORT QDeclarativeObjectScriptClass : public QDeclarativeScriptClass
+class Q_AUTOTEST_EXPORT QDeclarativeObjectScriptClass : public QScriptDeclarativeClass
{
public:
QDeclarativeObjectScriptClass(QDeclarativeEngine *);
@@ -115,10 +113,10 @@ public:
QDeclarativeContextData *evalContext,
QueryHints hints = 0);
- ScriptValue property(QObject *, const Identifier &);
+ Value property(QObject *, const Identifier &);
void setProperty(QObject *, const Identifier &name, const QScriptValue &,
- QDeclarativeContextData *evalContext = 0);
+ QScriptContext *context, QDeclarativeContextData *evalContext = 0);
virtual QStringList propertyNames(Object *);
virtual bool compare(Object *, Object *);
@@ -126,16 +124,14 @@ protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
QScriptClass::QueryFlags flags);
- virtual ScriptValue property(Object *, const Identifier &);
+ virtual Value property(Object *, const Identifier &);
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &);
virtual bool isQObject() const;
virtual QObject *toQObject(Object *, bool *ok = 0);
private:
-#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
friend class QDeclarativeObjectMethodScriptClass;
QDeclarativeObjectMethodScriptClass methods;
-#endif
QDeclarativeTypeNameCache::Data *lastTNData;
QDeclarativePropertyCache::Data *lastData;
diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp
index 69186b6..d1f209a 100644
--- a/src/declarative/qml/qdeclarativeparser.cpp
+++ b/src/declarative/qml/qdeclarativeparser.cpp
@@ -200,7 +200,7 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
}
QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
-: name(o.name), body(o.body), parameterNames(o.parameterNames)
+: name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
{
}
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index 57df04c..00fc65b 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -227,6 +227,7 @@ namespace QDeclarativeParser
QByteArray name;
QString body;
QList<QByteArray> parameterNames;
+ LocationSpan location;
};
// The list of dynamic properties
diff --git a/src/declarative/qml/qdeclarativescriptclass_p.h b/src/declarative/qml/qdeclarativescriptclass_p.h
deleted file mode 100644
index d8733db..0000000
--- a/src/declarative/qml/qdeclarativescriptclass_p.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVESCRIPTCLASS_P_H
-#define QDECLARATIVESCRIPTCLASS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtScript/qscriptclass.h>
-#include <private/qscriptdeclarativeclass_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeEngine;
-class QDeclarativeScriptClass : public QScriptDeclarativeClass
-{
-public:
- QDeclarativeScriptClass(QScriptEngine *);
-
- static QVariant toVariant(QDeclarativeEngine *, const QScriptValue &);
-
-#if (QT_VERSION <= QT_VERSION_CHECK(4, 6, 2)) && !defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
- struct Value : public QScriptValue {
- Value() : QScriptValue() {}
- Value(QScriptEngine *engine, int v) : QScriptValue(engine, v) {}
- Value(QScriptEngine *engine, uint v) : QScriptValue(engine, v) {}
- Value(QScriptEngine *engine, bool v) : QScriptValue(engine, v) {}
- Value(QScriptEngine *engine, double v) : QScriptValue(engine, v) {}
- Value(QScriptEngine *engine, float v) : QScriptValue(engine, v) {}
- Value(QScriptEngine *engine, const QString &v) : QScriptValue(engine, v) {}
- Value(QScriptEngine *, const QScriptValue &v) : QScriptValue(v) {}
- };
-
- typedef QScriptValue ScriptValue;
-#else
- typedef Value ScriptValue;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVESCRIPTCLASS_P_H
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index cba5bb9..ac49332 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -488,8 +488,8 @@ bool ProcessAST::visit(AST::UiImport *node)
} else if (import.type == QDeclarativeScriptParser::Import::Script) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import requires a qualifier"));
- error.setLine(node->importIdToken.startLine);
- error.setColumn(node->importIdToken.startColumn);
+ error.setLine(node->fileNameToken.startLine);
+ error.setColumn(node->fileNameToken.startColumn);
_parser->_errors << error;
return false;
}
@@ -535,7 +535,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
// { "time", Object::DynamicProperty::Time, "QTime" },
// { "date", Object::DynamicProperty::Date, "QDate" },
{ "date", Object::DynamicProperty::DateTime, "QDateTime" },
- { "var", Object::DynamicProperty::Variant, "QVariant" }
+ { "var", Object::DynamicProperty::Variant, "QVariant" },
+ { "variant", Object::DynamicProperty::Variant, "QVariant" }
};
const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
sizeof(propTypeNameToTypes[0]);
@@ -563,7 +564,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
_parser->_errors << error;
return false;
}
-
+
signal.parameterTypes << qtType;
signal.parameterNames << p->name->asString().toUtf8();
p = p->finish();
@@ -646,6 +647,11 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
property.location = location(node->firstSourceLocation(),
node->lastSourceLocation());
+ if (memberType == QLatin1String("var"))
+ qWarning().nospace() << qPrintable(_parser->_scriptFile) << ":" << property.location.start.line << ":"
+ << property.location.start.column << ": var type has been replaced by variant. "
+ << "Support will be removed entirely shortly.";
+
if (node->expression) { // default value
property.defaultValue = new Property;
property.defaultValue->parent = _stateStack.top().object;
@@ -828,6 +834,7 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
Object::DynamicSlot slot;
+ slot.location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
AST::FormalParameterList *f = funDecl->formals;
while (f) {
@@ -908,6 +915,7 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
clear();
const QString fileName = url.toString();
+ _scriptFile = fileName;
QTextStream stream(qmldata, QIODevice::ReadOnly);
stream.setCodec("UTF-8");
diff --git a/src/declarative/qml/qdeclarativestringconverters.cpp b/src/declarative/qml/qdeclarativestringconverters.cpp
index 5c88b9a..bbcc00b 100644
--- a/src/declarative/qml/qdeclarativestringconverters.cpp
+++ b/src/declarative/qml/qdeclarativestringconverters.cpp
@@ -82,10 +82,6 @@ QVariant QDeclarativeStringConverters::variantFromString(const QString &s)
{
if (s.isEmpty())
return QVariant(s);
- if (s.startsWith(QLatin1Char('\'')) && s.endsWith(QLatin1Char('\''))) {
- QString data = s.mid(1, s.length() - 2);
- return QVariant(data);
- }
bool ok = false;
QRectF r = rectFFromString(s, &ok);
if (ok) return QVariant(r);
@@ -104,6 +100,10 @@ QVariant QDeclarativeStringConverters::variantFromString(const QString &s)
QVariant QDeclarativeStringConverters::variantFromString(const QString &s, int preferredType, bool *ok)
{
switch (preferredType) {
+ case QMetaType::Int:
+ return QVariant(int(qRound(s.toDouble(ok))));
+ case QMetaType::UInt:
+ return QVariant(uint(qRound(s.toDouble(ok))));
case QMetaType::QColor:
return QVariant::fromValue(colorFromString(s, ok));
case QMetaType::QDate:
diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
index 9cac3e1..2a3417a 100644
--- a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
@@ -62,7 +62,7 @@ struct TypeNameData : public QScriptDeclarativeClass::Object {
};
QDeclarativeTypeNameScriptClass::QDeclarativeTypeNameScriptClass(QDeclarativeEngine *bindEngine)
-: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)),
+: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)),
engine(bindEngine), object(0), type(0)
{
}
@@ -139,7 +139,7 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na
return 0;
}
-QDeclarativeTypeNameScriptClass::ScriptValue
+QDeclarativeTypeNameScriptClass::Value
QDeclarativeTypeNameScriptClass::property(Object *obj, const Identifier &name)
{
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
@@ -159,7 +159,7 @@ void QDeclarativeTypeNameScriptClass::setProperty(Object *o, const Identifier &n
Q_ASSERT(!type);
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- ep->objectClass->setProperty(((TypeNameData *)o)->object, n, v);
+ ep->objectClass->setProperty(((TypeNameData *)o)->object, n, v, context());
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass_p.h b/src/declarative/qml/qdeclarativetypenamescriptclass_p.h
index 8e07f02..310e14e 100644
--- a/src/declarative/qml/qdeclarativetypenamescriptclass_p.h
+++ b/src/declarative/qml/qdeclarativetypenamescriptclass_p.h
@@ -54,16 +54,15 @@
//
#include "private/qdeclarativeengine_p.h"
+#include <private/qscriptdeclarativeclass_p.h>
#include <QtScript/qscriptclass.h>
-#include <private/qdeclarativescriptclass_p.h>
-
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QDeclarativeType;
class QDeclarativeTypeNameCache;
-class QDeclarativeTypeNameScriptClass : public QDeclarativeScriptClass
+class QDeclarativeTypeNameScriptClass : public QScriptDeclarativeClass
{
public:
QDeclarativeTypeNameScriptClass(QDeclarativeEngine *);
@@ -77,7 +76,7 @@ protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
QScriptClass::QueryFlags flags);
- virtual ScriptValue property(Object *, const Identifier &);
+ virtual Value property(Object *, const Identifier &);
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &);
private:
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index 839e0dd..261c84a 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -47,10 +47,6 @@
QT_BEGIN_NAMESPACE
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
-Q_DECLARE_METATYPE(QEasingCurve);
-#endif
-
template<typename T>
int qmlRegisterValueTypeEnums(const char *qmlName)
{
@@ -82,29 +78,18 @@ QDeclarativeValueTypeFactory::QDeclarativeValueTypeFactory()
// ### Optimize
for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii)
valueTypes[ii] = valueType(ii);
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
- easingType = qMetaTypeId<QEasingCurve>();
- easingValueType = valueType(easingType);
-#endif
}
QDeclarativeValueTypeFactory::~QDeclarativeValueTypeFactory()
{
for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii)
delete valueTypes[ii];
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
- delete easingValueType;
-#endif
}
bool QDeclarativeValueTypeFactory::isValueType(int idx)
{
if ((uint)idx < QVariant::UserType)
return true;
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
- if (idx == qMetaTypeId<QEasingCurve>())
- return true;
-#endif
return false;
}
@@ -116,9 +101,6 @@ void QDeclarativeValueTypeFactory::registerValueTypes()
QDeclarativeValueType *QDeclarativeValueTypeFactory::operator[](int idx) const
{
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
- if (idx == easingType) return easingValueType;
-#endif
return valueTypes[idx];
}
@@ -140,17 +122,11 @@ QDeclarativeValueType *QDeclarativeValueTypeFactory::valueType(int t)
return new QDeclarativeRectFValueType;
case QVariant::Vector3D:
return new QDeclarativeVector3DValueType;
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
case QVariant::EasingCurve:
return new QDeclarativeEasingValueType;
-#endif
case QVariant::Font:
return new QDeclarativeFontValueType;
default:
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
- if (t == qMetaTypeId<QEasingCurve>())
- return new QDeclarativeEasingValueType;
-#endif
return 0;
}
}
@@ -566,11 +542,7 @@ void QDeclarativeEasingValueType::write(QObject *obj, int idx, QDeclarativePrope
QVariant QDeclarativeEasingValueType::value()
{
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
return QVariant(easing);
-#else
- return QVariant::fromValue<QEasingCurve>(easing);
-#endif
}
void QDeclarativeEasingValueType::setValue(QVariant value)
@@ -619,7 +591,7 @@ void QDeclarativeEasingValueType::setPeriod(qreal period)
}
QDeclarativeFontValueType::QDeclarativeFontValueType(QObject *parent)
-: QDeclarativeValueType(parent), hasPixelSize(false)
+: QDeclarativeValueType(parent), pixelSizeSet(false), pointSizeSet(false)
{
}
@@ -627,6 +599,8 @@ void QDeclarativeFontValueType::read(QObject *obj, int idx)
{
void *a[] = { &font, 0 };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
+ pixelSizeSet = false;
+ pointSizeSet = false;
}
void QDeclarativeFontValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
@@ -724,13 +698,17 @@ qreal QDeclarativeFontValueType::pointSize() const
void QDeclarativeFontValueType::setPointSize(qreal size)
{
- if (hasPixelSize) {
+ if (pixelSizeSet) {
qWarning() << "Both point size and pixel size set. Using pixel size.";
return;
}
- if (size >= 0.0)
+ if (size >= 0.0) {
+ pointSizeSet = true;
font.setPointSizeF(size);
+ } else {
+ pointSizeSet = false;
+ }
}
int QDeclarativeFontValueType::pixelSize() const
@@ -741,10 +719,12 @@ int QDeclarativeFontValueType::pixelSize() const
void QDeclarativeFontValueType::setPixelSize(int size)
{
if (size >=0) {
+ if (pointSizeSet)
+ qWarning() << "Both point size and pixel size set. Using pixel size.";
font.setPixelSize(size);
- hasPixelSize = true;
+ pixelSizeSet = true;
} else {
- hasPixelSize = false;
+ pixelSizeSet = false;
}
}
diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h
index 1fe8bd2..5bfc27d 100644
--- a/src/declarative/qml/qdeclarativevaluetype_p.h
+++ b/src/declarative/qml/qdeclarativevaluetype_p.h
@@ -90,10 +90,6 @@ public:
private:
QDeclarativeValueType *valueTypes[QVariant::UserType - 1];
-#if (QT_VERSION < QT_VERSION_CHECK(4,7,0))
- int easingType;
- QDeclarativeValueType *easingValueType;
-#endif
};
class Q_AUTOTEST_EXPORT QDeclarativePointFValueType : public QDeclarativeValueType
@@ -399,7 +395,8 @@ public:
private:
QFont font;
- bool hasPixelSize;
+ bool pixelSizeSet;
+ bool pointSizeSet;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index f7902b9..fdb71c6 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -55,7 +55,7 @@ struct QDeclarativeValueTypeReference : public QScriptDeclarativeClass::Object {
};
QDeclarativeValueTypeScriptClass::QDeclarativeValueTypeScriptClass(QDeclarativeEngine *bindEngine)
-: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
+: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
{
}
@@ -100,7 +100,7 @@ QDeclarativeValueTypeScriptClass::queryProperty(Object *obj, const Identifier &n
return rv;
}
-QDeclarativeValueTypeScriptClass::ScriptValue QDeclarativeValueTypeScriptClass::property(Object *obj, const Identifier &)
+QDeclarativeValueTypeScriptClass::Value QDeclarativeValueTypeScriptClass::property(Object *obj, const Identifier &)
{
QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
@@ -113,7 +113,7 @@ QDeclarativeValueTypeScriptClass::ScriptValue QDeclarativeValueTypeScriptClass::
}
void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier &,
- const QScriptValue &value)
+ const QScriptValue &value)
{
QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
@@ -122,7 +122,7 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
if (delBinding)
delBinding->destroy();
- QVariant v = QDeclarativeScriptClass::toVariant(engine, value);
+ QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
ref->type->read(ref->object, ref->property);
QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h b/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h
index 31bd415..2bbb61f 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h
@@ -54,13 +54,13 @@
//
-#include <private/qdeclarativescriptclass_p.h>
+#include <private/qscriptdeclarativeclass_p.h>
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QDeclarativeValueType;
-class QDeclarativeValueTypeScriptClass : public QDeclarativeScriptClass
+class QDeclarativeValueTypeScriptClass : public QScriptDeclarativeClass
{
public:
QDeclarativeValueTypeScriptClass(QDeclarativeEngine *);
@@ -70,7 +70,7 @@ public:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
QScriptClass::QueryFlags flags);
- virtual ScriptValue property(Object *, const Identifier &);
+ virtual Value property(Object *, const Identifier &);
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &);
virtual QVariant toVariant(Object *, bool *ok = 0);
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 5ba7f9b..0addfabd 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -236,13 +236,44 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
}
} else {
QDeclarative_setParent_noEvent(o, parent);
- // o->setParent(parent);
}
}
stack.push(o);
}
break;
+ case QDeclarativeInstruction::CreateSimpleObject:
+ {
+ QObject *o = (QObject *)operator new(instr.createSimple.typeSize +
+ sizeof(QDeclarativeDeclarativeData));
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ ::memset(o, 0, instr.createSimple.typeSize + sizeof(QDeclarativeDeclarativeData));
+#else
+ // faster than memset
+ ::bzero(o, instr.createSimple.typeSize + sizeof(QDeclarativeDeclarativeData));
+#endif
+ instr.createSimple.create(o);
+
+ QDeclarativeDeclarativeData *ddata =
+ (QDeclarativeDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize);
+ ddata->lineNumber = instr.line;
+ ddata->columnNumber = instr.createSimple.column;
+
+ QObjectPrivate::get(o)->declarativeData = ddata;
+ ddata->context = ddata->outerContext = ctxt;
+ ddata->nextContextObject = ctxt->contextObjects;
+ if (ddata->nextContextObject)
+ ddata->nextContextObject->prevContextObject = &ddata->nextContextObject;
+ ddata->prevContextObject = &ctxt->contextObjects;
+ ctxt->contextObjects = ddata;
+
+ QObject *parent = stack.top();
+ QDeclarative_setParent_noEvent(o, parent);
+
+ stack.push(o);
+ }
+ break;
+
case QDeclarativeInstruction::SetId:
{
QObject *target = stack.top();
@@ -314,6 +345,26 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
}
break;
+ case QDeclarativeInstruction::StoreVariantInteger:
+ {
+ QObject *target = stack.top();
+ QVariant v(instr.storeInteger.value);
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeString.propertyIndex, a);
+ }
+ break;
+
+ case QDeclarativeInstruction::StoreVariantDouble:
+ {
+ QObject *target = stack.top();
+ QVariant v(instr.storeDouble.value);
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeString.propertyIndex, a);
+ }
+ break;
+
case QDeclarativeInstruction::StoreString:
{
QObject *target = stack.top();
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 2644ecf..2e2a8e8 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -671,7 +671,8 @@ QScriptValue QDeclarativeVMEMetaObject::method(int index)
// XXX We should evaluate all methods in a single big script block to
// improve the call time between dynamic methods defined on the same
// object
- methods[index] = QDeclarativeExpressionPrivate::evalInObjectScope(ctxt, object, code);
+ methods[index] = QDeclarativeExpressionPrivate::evalInObjectScope(ctxt, object, code, ctxt->url.toString(),
+ data->lineNumber, 0);
}
return methods[index];
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index f13dd34..76390c9 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -94,7 +94,7 @@ struct QDeclarativeVMEMetaData
int parameterCount;
int bodyOffset;
int bodyLength;
- int scriptProgram;
+ int lineNumber;
};
PropertyData *propertyData() const {
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index ddb0ece..138d979 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -107,16 +107,20 @@ class QDeclarativeWorkerScriptEnginePrivate : public QObject
{
Q_OBJECT
public:
+ enum WorkerEventTypes {
+ WorkerDestroyEvent = QEvent::User + 100
+ };
+
QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *eng);
- struct ScriptEngine : public QDeclarativeScriptEngine
+ struct ScriptEngine : public QDeclarativeScriptEngine
{
ScriptEngine(QDeclarativeWorkerScriptEnginePrivate *parent) : QDeclarativeScriptEngine(0), p(parent), accessManager(0) {}
~ScriptEngine() { delete accessManager; }
QDeclarativeWorkerScriptEnginePrivate *p;
QNetworkAccessManager *accessManager;
- virtual QNetworkAccessManager *networkAccessManager() {
+ virtual QNetworkAccessManager *networkAccessManager() {
if (!accessManager) {
if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) {
accessManager = p->qmlengine->networkAccessManagerFactory()->create(this);
@@ -159,6 +163,9 @@ public:
static QScriptValue onMessage(QScriptContext *ctxt, QScriptEngine *engine);
static QScriptValue sendMessage(QScriptContext *ctxt, QScriptEngine *engine);
+signals:
+ void stopThread();
+
protected:
virtual bool event(QEvent *);
@@ -182,7 +189,7 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::onMessage(QScriptContext *ct
if (!script)
return engine->undefinedValue();
- if (ctxt->argumentCount() >= 1)
+ if (ctxt->argumentCount() >= 1)
script->callback = ctxt->argument(0);
return script->callback;
@@ -198,13 +205,13 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::sendMessage(QScriptContext *
int id = ctxt->thisObject().data().toVariant().toInt();
WorkerScript *script = p->workers.value(id);
- if (!script)
+ if (!script)
return engine->undefinedValue();
QMutexLocker(&p->m_lock);
- if (script->owner)
- QCoreApplication::postEvent(script->owner,
+ if (script->owner)
+ QCoreApplication::postEvent(script->owner,
new WorkerDataEvent(0, scriptValueToVariant(ctxt->argument(0))));
return engine->undefinedValue();
@@ -226,7 +233,7 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::getWorker(int id)
QScriptValue api = workerEngine->newObject();
api.setData(script->id);
- api.setProperty(QLatin1String("onMessage"), workerEngine->newFunction(onMessage),
+ api.setProperty(QLatin1String("onMessage"), workerEngine->newFunction(onMessage),
QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
api.setProperty(QLatin1String("sendMessage"), workerEngine->newFunction(sendMessage));
@@ -246,6 +253,9 @@ bool QDeclarativeWorkerScriptEnginePrivate::event(QEvent *event)
WorkerLoadEvent *workerEvent = static_cast<WorkerLoadEvent *>(event);
processLoad(workerEvent->workerId(), workerEvent->url());
return true;
+ } else if (event->type() == (QEvent::Type)WorkerDestroyEvent) {
+ emit stopThread();
+ return true;
} else {
return QObject::event(event);
}
@@ -362,7 +372,7 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::variantToScriptValue(const Q
QVariantList list = qvariant_cast<QVariantList>(value);
QScriptValue rv = engine->newArray(list.count());
- for (quint32 ii = 0; ii < quint32(list.count()); ++ii)
+ for (quint32 ii = 0; ii < quint32(list.count()); ++ii)
rv.setProperty(ii, variantToScriptValue(list.at(ii), engine));
return rv;
@@ -372,7 +382,7 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::variantToScriptValue(const Q
QScriptValue rv = engine->newObject();
- for (QVariantHash::ConstIterator iter = hash.begin(); iter != hash.end(); ++iter)
+ for (QVariantHash::ConstIterator iter = hash.begin(); iter != hash.end(); ++iter)
rv.setProperty(iter.key(), variantToScriptValue(iter.value(), engine));
return rv;
@@ -429,6 +439,7 @@ QDeclarativeWorkerScriptEngine::QDeclarativeWorkerScriptEngine(QDeclarativeEngin
: QThread(parent), d(new QDeclarativeWorkerScriptEnginePrivate(parent))
{
d->m_lock.lock();
+ connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection);
start(QThread::LowPriority);
d->m_wait.wait(&d->m_lock);
d->moveToThread(this);
@@ -440,8 +451,10 @@ QDeclarativeWorkerScriptEngine::~QDeclarativeWorkerScriptEngine()
d->m_lock.lock();
qDeleteAll(d->workers);
d->workers.clear();
+ QCoreApplication::postEvent(d, new QEvent((QEvent::Type)QDeclarativeWorkerScriptEnginePrivate::WorkerDestroyEvent));
d->m_lock.unlock();
+ wait();
d->deleteLater();
}
@@ -504,36 +517,10 @@ void QDeclarativeWorkerScriptEngine::run()
Messages can be passed between the new thread and the parent thread
using sendMessage() and the onMessage() handler.
-
- Here is an example:
-
- \qml
- import Qt 4.6
- Rectangle {
- width: 300
- height: 300
-
- Text {
- id: myText
- text: 'Click anywhere'
- }
+ Here is an example:
- WorkerScript {
- id: myWorker
- source: "script.js"
-
- onMessage: {
- myText.text = messageObject.reply
- }
- }
-
- MouseArea {
- anchors.fill: parent
- onClicked: myWorker.sendMessage( {'x': mouse.x, 'y': mouse.y} );
- }
- }
- \endqml
+ \snippet doc/src/snippets/declarative/workerscript.qml 0
The above worker script specifies a javascript file, "script.js", that handles
the operations to be performed in the new thread:
@@ -541,10 +528,10 @@ void QDeclarativeWorkerScriptEngine::run()
\qml
WorkerScript.onMessage = function(message) {
// ... long-running operations and calculations are done here
- WorkerScript.sendMessage( {'reply': 'Mouse is at ' + message.x + ',' + message.y} );
+ WorkerScript.sendMessage({ 'reply': 'Mouse is at ' + message.x + ',' + message.y })
}
\endqml
-
+
When the user clicks anywhere within the rectangle, \c sendMessage() is
called, triggering the \tt WorkerScript.onMessage() handler in
\tt source.js. This in turn sends a reply message that is then received
@@ -578,7 +565,7 @@ void QDeclarativeWorkerScript::setSource(const QUrl &source)
m_source = source;
- if (m_engine)
+ if (m_engine)
m_engine->executeUrl(m_scriptId, m_source);
emit sourceChanged();
@@ -632,7 +619,7 @@ bool QDeclarativeWorkerScript::event(QEvent *event)
if (engine) {
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
- QScriptValue value =
+ QScriptValue value =
QDeclarativeWorkerScriptEnginePrivate::variantToScriptValue(workerEvent->data(), scriptEngine);
emit message(value);
}
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index e2f0c67..1087f44 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -121,7 +121,6 @@ HEADERS += \
$$PWD/qdeclarativetypenamescriptclass_p.h \
$$PWD/qdeclarativelistscriptclass_p.h \
$$PWD/qdeclarativeworkerscript_p.h \
- $$PWD/qdeclarativescriptclass_p.h \
$$PWD/qdeclarativeguard_p.h \
$$PWD/qdeclarativeimageprovider.h \
$$PWD/qdeclarativenetworkaccessmanagerfactory.h \