summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/parser/qdeclarativejs.g11
-rw-r--r--src/declarative/qml/parser/qdeclarativejsparser.cpp11
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp88
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp55
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h7
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp85
-rw-r--r--src/declarative/qml/qdeclarativedom.cpp6
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp132
-rw-r--r--src/declarative/qml/qdeclarativeengine.h3
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h3
-rw-r--r--src/declarative/qml/qdeclarativefastproperties.cpp92
-rw-r--r--src/declarative/qml/qdeclarativefastproperties_p.h (renamed from src/declarative/qml/qdeclarativescript.cpp)63
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.cpp6
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.h2
-rw-r--r--src/declarative/qml/qdeclarativelist.h7
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeproperty.h5
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp11
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase.cpp4
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp461
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h17
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp6
-rw-r--r--src/declarative/qml/qml.pri3
23 files changed, 852 insertions, 228 deletions
diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g
index 0256c52..6434d10 100644
--- a/src/declarative/qml/parser/qdeclarativejs.g
+++ b/src/declarative/qml/parser/qdeclarativejs.g
@@ -654,11 +654,6 @@ case $rule_number: {
node = makeAstNode<AST::UiImport>(driver->nodePool(), importIdLiteral->value);
node->fileNameToken = loc(2);
} else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
- QString text;
- for (AST::UiQualifiedId *q = qualifiedId; q; q = q->next) {
- text += q->name->asString();
- if (q->next) text += QLatin1String(".");
- }
node = makeAstNode<AST::UiImport>(driver->nodePool(), qualifiedId);
node->fileNameToken = loc(2);
}
@@ -1109,6 +1104,9 @@ case $rule_number: {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
return false; // ### remove me
}
+
+ loc(1).length = lexer->tokenLength();
+
AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
node->literalToken = loc(1);
sym(1).Node = node;
@@ -1126,6 +1124,9 @@ case $rule_number: {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
return false;
}
+
+ loc(1).length = lexer->tokenLength();
+
AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
node->literalToken = loc(1);
sym(1).Node = node;
diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp
index 9205ef4..3cf73b1 100644
--- a/src/declarative/qml/parser/qdeclarativejsparser.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp
@@ -273,11 +273,6 @@ case 20: {
node = makeAstNode<AST::UiImport>(driver->nodePool(), importIdLiteral->value);
node->fileNameToken = loc(2);
} else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
- QString text;
- for (AST::UiQualifiedId *q = qualifiedId; q; q = q->next) {
- text += q->name->asString();
- if (q->next) text += QLatin1String(".");
- }
node = makeAstNode<AST::UiImport>(driver->nodePool(), qualifiedId);
node->fileNameToken = loc(2);
}
@@ -571,6 +566,9 @@ case 76: {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
return false; // ### remove me
}
+
+ loc(1).length = lexer->tokenLength();
+
AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
node->literalToken = loc(1);
sym(1).Node = node;
@@ -582,6 +580,9 @@ case 77: {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
return false;
}
+
+ loc(1).length = lexer->tokenLength();
+
AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
node->literalToken = loc(1);
sym(1).Node = node;
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 1acca2f..67750a4 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -53,11 +53,15 @@
#include <QtCore/qnumeric.h>
#include <private/qdeclarativeanchors_p_p.h>
#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativefastproperties_p.h>
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);
+
+Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties);
using namespace QDeclarativeJS;
@@ -334,6 +338,8 @@ struct Instr {
Subscribe, // subscribe
SubscribeId, // subscribe
+ FetchAndSubscribe, // fetchAndSubscribe
+
LoadId, // load
LoadScope, // load
LoadRoot, // load
@@ -433,6 +439,14 @@ struct Instr {
qint8 output;
qint8 objectReg;
quint8 exceptionId;
+ quint16 subscription;
+ quint16 function;
+ } fetchAndSubscribe;
+ struct {
+ quint8 type;
+ qint8 output;
+ qint8 objectReg;
+ quint8 exceptionId;
quint32 index;
} fetch;
struct {
@@ -937,6 +951,9 @@ static void dumpInstruction(const Instr *instr)
case Instr::SubscribeId:
qWarning().nospace() << "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;
+ break;
case Instr::LoadId:
qWarning().nospace() << "LoadId" << "\t\t\t" << instr->load.index << "\t" << instr->load.reg;
break;
@@ -1070,6 +1087,8 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
QDeclarativeContextData *context, QDeclarativeDelayedError *error,
QObject *scope, QObject *output)
{
+ Q_Q(QDeclarativeCompiledBindings);
+
error->removeError();
Register registers[32];
@@ -1081,6 +1100,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
instr += instrIndex;
const char *data = program->data();
+ // return;
#ifdef COMPILEDBINDINGS_DEBUG
qWarning().nospace() << "Begin binding run";
#endif
@@ -1107,6 +1127,32 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
}
break;
+ case Instr::FetchAndSubscribe:
+ {
+ const Register &input = registers[instr->fetchAndSubscribe.objectReg];
+ Register &output = registers[instr->fetchAndSubscribe.output];
+
+ if (input.isUndefined()) {
+ throwException(instr->fetchAndSubscribe.exceptionId, error, program, context);
+ return;
+ }
+
+ QObject *object = input.getQObject();
+ if (!object) {
+ output.setUndefined();
+ } else {
+ int subIdx = instr->fetchAndSubscribe.subscription;
+ QDeclarativeCompiledBindingsPrivate::Subscription *sub = 0;
+ if (subIdx != -1) {
+ sub = (subscriptions + subIdx);
+ sub->target = q;
+ sub->targetMethod = methodCount + subIdx;
+ }
+ fastProperties()->accessor(instr->fetchAndSubscribe.function)(object, output.typeDataPtr(), sub);
+ }
+ }
+ break;
+
case Instr::LoadId:
registers[instr->load.reg].setQObject(context->idValues[instr->load.index].data());
break;
@@ -2376,29 +2422,41 @@ bool QDeclarativeBindingCompilerPrivate::buildName(QStringList &name,
return true;
}
-
bool QDeclarativeBindingCompilerPrivate::fetch(Result &rv, const QMetaObject *mo, int reg,
- int idx, const QStringList &subName, QDeclarativeJS::AST::ExpressionNode *node)
+ int idx, const QStringList &subName,
+ QDeclarativeJS::AST::ExpressionNode *node)
{
QMetaProperty prop = mo->property(idx);
rv.metaObject = 0;
rv.type = 0;
- if (subscription(subName, &rv) && prop.hasNotifySignal() && prop.notifySignalIndex() != -1) {
- Instr sub;
- sub.common.type = Instr::Subscribe;
- sub.subscribe.offset = subscriptionIndex(subName);
- sub.subscribe.reg = reg;
- sub.subscribe.index = prop.notifySignalIndex();
- bytecode << sub;
- }
+ int fastFetchIndex = fastProperties()->accessorIndexForProperty(mo, idx);
Instr fetch;
- fetch.common.type = Instr::Fetch;
- fetch.fetch.objectReg = reg;
- fetch.fetch.index = idx;
- fetch.fetch.output = reg;
- fetch.fetch.exceptionId = exceptionId(node);
+
+ if (!qmlDisableFastProperties() && fastFetchIndex != -1) {
+ fetch.common.type = Instr::FetchAndSubscribe;
+ fetch.fetchAndSubscribe.objectReg = reg;
+ fetch.fetchAndSubscribe.output = reg;
+ fetch.fetchAndSubscribe.function = fastFetchIndex;
+ fetch.fetchAndSubscribe.subscription = subscriptionIndex(subName);
+ fetch.fetchAndSubscribe.exceptionId = exceptionId(node);
+ } else {
+ if (subscription(subName, &rv) && prop.hasNotifySignal() && prop.notifySignalIndex() != -1) {
+ Instr sub;
+ sub.common.type = Instr::Subscribe;
+ sub.subscribe.offset = subscriptionIndex(subName);
+ sub.subscribe.reg = reg;
+ sub.subscribe.index = prop.notifySignalIndex();
+ bytecode << sub;
+ }
+
+ fetch.common.type = Instr::Fetch;
+ fetch.fetch.objectReg = reg;
+ fetch.fetch.index = idx;
+ fetch.fetch.output = reg;
+ fetch.fetch.exceptionId = exceptionId(node);
+ }
rv.type = prop.userType();
rv.metaObject = engine->metaObjectForType(rv.type);
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index a9d90f3..56af5f5 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -80,7 +80,7 @@
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
-DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATISTICS_DUMP);
+DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS);
DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
using namespace QDeclarativeParser;
@@ -617,6 +617,7 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
void QDeclarativeCompiler::compileTree(Object *tree)
{
compileState.root = tree;
+ componentStat.lineNumber = tree->location.start.line;
if (!buildObject(tree, BindingContext()) || !completeComponentBuild())
return;
@@ -2428,10 +2429,18 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
propertyType = QVariant::Color;
type = "QColor";
break;
+ case Object::DynamicProperty::Time:
+ propertyType = QVariant::Time;
+ type = "QTime";
+ break;
case Object::DynamicProperty::Date:
propertyType = QVariant::Date;
type = "QDate";
break;
+ case Object::DynamicProperty::DateTime:
+ propertyType = QVariant::DateTime;
+ type = "QDateTime";
+ break;
}
((QDeclarativeVMEMetaData *)dynamicData.data())->propertyCount++;
@@ -2776,7 +2785,7 @@ bool QDeclarativeCompiler::completeComponentBuild()
if (index != -1) {
binding.dataType = BindingReference::Experimental;
binding.compiledIndex = index;
- componentStat.optimizedBindings++;
+ componentStat.optimizedBindings.append(iter.key()->location);
continue;
}
@@ -2810,7 +2819,7 @@ bool QDeclarativeCompiler::completeComponentBuild()
QByteArray((const char *)expression.constData(),
expression.length() * sizeof(QChar));
- componentStat.scriptBindings++;
+ componentStat.scriptBindings.append(iter.key()->location);
}
if (bindingCompiler.isValid()) {
@@ -2832,8 +2841,44 @@ void QDeclarativeCompiler::dumpStats()
qWarning().nospace() << " Component Line " << stat.lineNumber;
qWarning().nospace() << " Total Objects: " << stat.objects;
qWarning().nospace() << " IDs Used: " << stat.ids;
- qWarning().nospace() << " Optimized Bindings: " << stat.optimizedBindings;
- qWarning().nospace() << " QScript Bindings: " << stat.scriptBindings;
+ qWarning().nospace() << " Optimized Bindings: " << stat.optimizedBindings.count();
+
+ {
+ QByteArray output;
+ for (int ii = 0; ii < stat.optimizedBindings.count(); ++ii) {
+ if (0 == (ii % 10)) {
+ if (ii) output.append("\n");
+ output.append(" ");
+ }
+
+ output.append("(");
+ output.append(QByteArray::number(stat.optimizedBindings.at(ii).start.line));
+ output.append(":");
+ output.append(QByteArray::number(stat.optimizedBindings.at(ii).start.column));
+ output.append(") ");
+ }
+ if (!output.isEmpty())
+ qWarning().nospace() << output.constData();
+ }
+
+ qWarning().nospace() << " QScript Bindings: " << stat.scriptBindings.count();
+ {
+ QByteArray output;
+ for (int ii = 0; ii < stat.scriptBindings.count(); ++ii) {
+ if (0 == (ii % 10)) {
+ if (ii) output.append("\n");
+ output.append(" ");
+ }
+
+ output.append("(");
+ output.append(QByteArray::number(stat.scriptBindings.at(ii).start.line));
+ output.append(":");
+ output.append(QByteArray::number(stat.scriptBindings.at(ii).start.column));
+ output.append(") ");
+ }
+ if (!output.isEmpty())
+ qWarning().nospace() << output.constData();
+ }
}
}
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index a81259b..e5836d1 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -318,14 +318,13 @@ private:
struct ComponentStat
{
- ComponentStat()
- : ids(0), scriptBindings(0), optimizedBindings(0), objects(0) {}
+ ComponentStat() : ids(0), objects(0) {}
int lineNumber;
int ids;
- int scriptBindings;
- int optimizedBindings;
+ QList<QDeclarativeParser::LocationSpan> scriptBindings;
+ QList<QDeclarativeParser::LocationSpan> optimizedBindings;
int objects;
};
ComponentStat componentStat;
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 2b8cf70..a9224ad 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -71,31 +71,30 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
Contexts allow data to be exposed to the QML components instantiated by the
QML engine.
- Each QDeclarativeContext contains a set of properties, distinct from
- its QObject properties, that allow data to be
- explicitly bound to a context by name. The context properties are defined or
- updated by calling QDeclarativeContext::setContextProperty(). The following example shows
- a Qt model being bound to a context and then accessed from a QML file.
+ Each QDeclarativeContext contains a set of properties, distinct from its QObject
+ properties, that allow data to be explicitly bound to a context by name. The
+ context properties are defined and updated by calling
+ QDeclarativeContext::setContextProperty(). The following example shows a Qt model
+ being bound to a context and then accessed from a QML file.
\code
QDeclarativeEngine engine;
- QDeclarativeContext context(engine.rootContext());
- context.setContextProperty("myModel", modelData);
+ QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());
+ context->setContextProperty("myModel", modelData);
QDeclarativeComponent component(&engine, "ListView { model=myModel }");
- component.create(&context);
+ component.create(context);
\endcode
- To simplify binding and maintaining larger data sets, QObject's can be
- added to a QDeclarativeContext. These objects are known as the context's default
- objects. In this case all the properties of the QObject are
- made available by name in the context, as though they were all individually
- added by calling QDeclarativeContext::setContextProperty(). Changes to the property's
- values are detected through the property's notify signal. This method is
- also slightly more faster than manually adding property values.
+ To simplify binding and maintaining larger data sets, a context object can be set
+ on a QDeclarativeContext. All the properties of the context object are available
+ by name in the context, as though they were all individually added through calls
+ to QDeclarativeContext::setContextProperty(). Changes to the property's values are
+ detected through the property's notify signal. Setting a context object is both
+ faster and easier than manually adding and maintaing context property values.
- The following example has the same effect as the one above, but it is
- achieved using a default object.
+ The following example has the same effect as the previous one, but it uses a context
+ object.
\code
class MyDataSet : ... {
@@ -104,46 +103,42 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
...
};
- MyDataSet myDataSet;
+ MyDataSet *myDataSet = new MyDataSet;
QDeclarativeEngine engine;
- QDeclarativeContext context(engine.rootContext());
- context.setContextObject(&myDataSet);
+ QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());
+ context->setContextObject(myDataSet);
QDeclarativeComponent component(&engine, "ListView { model=myModel }");
- component.create(&context);
+ component.create(context);
\endcode
- Default objects added first take precedence over those added later. All properties
- added explicitly by QDeclarativeContext::setContextProperty() take precedence over default
- object properties.
+ All properties added explicitly by QDeclarativeContext::setContextProperty() take
+ precedence over context object's properties.
- Contexts are hierarchal, with the \l {QDeclarativeEngine::rootContext()}{root context}
- being created by the QDeclarativeEngine. A component instantiated in a given context
- has access to that context's data, as well as the data defined by its
- ancestor contexts. Data values (including those added implicitly by the
- default objects) in a context override those in ancestor contexts. Data
- that should be available to all components instantiated by the QDeclarativeEngine
- should be added to the \l {QDeclarativeEngine::rootContext()}{root context}.
+ Contexts form a hierarchy. The root of this heirarchy is the QDeclarativeEngine's
+ \l {QDeclarativeEngine::rootContext()}{root context}. A component instance can
+ access the data in its own context, as well as all its ancestor contexts. Data
+ can be made available to all instances by modifying the
+ \l {QDeclarativeEngine::rootContext()}{root context}.
- In the following example,
+ The following example defines two contexts - \c context1 and \c context2. The
+ second context overrides the "b" context property inherited from the first with a
+ new value.
\code
QDeclarativeEngine engine;
- QDeclarativeContext context1(engine.rootContext());
- QDeclarativeContext context2(&context1);
- QDeclarativeContext context3(&context2);
-
- context1.setContextProperty("a", 12);
- context2.setContextProperty("b", 13);
- context3.setContextProperty("a", 14);
- context3.setContextProperty("c", 14);
+ QDeclarativeContext *context1 = new QDeclarativeContext(engine.rootContext());
+ QDeclarativeContext *context2 = new QDeclarativeContext(context1);
+
+ context1->setContextProperty("a", 12);
+ context1->setContextProperty("b", 12);
+
+ context2->setContextProperty("b", 15);
\endcode
- a QML component instantiated in context1 would have access to the "a" data,
- a QML component instantiated in context2 would have access to the "a" and
- "b" data, and a QML component instantiated in context3 would have access to
- the "a", "b" and "c" data - although its "a" data would return 14, unlike
- that in context1 or context2.
+ While QML objects instantiated in a context are not strictly owned by that
+ context, their bindings are. If a context is destroyed, the property bindings of
+ outstanding QML objects will stop evaluating.
*/
/*! \internal */
diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp
index 366750e..dec30a1 100644
--- a/src/declarative/qml/qdeclarativedom.cpp
+++ b/src/declarative/qml/qdeclarativedom.cpp
@@ -480,9 +480,15 @@ int QDeclarativeDomDynamicProperty::propertyType() const
case QDeclarativeParser::Object::DynamicProperty::Color:
return QMetaType::type("QColor");
+ case QDeclarativeParser::Object::DynamicProperty::Time:
+ return QMetaType::type("QTime");
+
case QDeclarativeParser::Object::DynamicProperty::Date:
return QMetaType::type("QDate");
+ case QDeclarativeParser::Object::DynamicProperty::DateTime:
+ return QMetaType::type("QDateTime");
+
case QDeclarativeParser::Object::DynamicProperty::Int:
return QMetaType::type("int");
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 2f0ec24..bb742ee 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -178,10 +178,16 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
#endif
foreach (const QString &path, QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts)) {
QString canonicalPath = QDir(path).canonicalPath();
- if (!canonicalPath.isEmpty() && !environmentImportPath.contains(canonicalPath))
- environmentImportPath.append(canonicalPath);
+ if (!canonicalPath.isEmpty() && !fileImportPath.contains(canonicalPath))
+ fileImportPath.append(canonicalPath);
}
}
+#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
+ QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
+ if (!builtinPath.isEmpty())
+ fileImportPath += builtinPath;
+#endif
+
}
QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
@@ -580,13 +586,13 @@ void QDeclarativeEngine::removeImageProvider(const QString &providerId)
delete d->imageProviders.take(providerId);
}
-QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url)
+QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
{
QMutexLocker locker(&mutex);
QImage image;
QDeclarativeImageProvider *provider = imageProviders.value(url.host());
if (provider)
- image = provider->request(url.path().mid(1));
+ image = provider->request(url.path().mid(1), size, req_size);
return image;
}
@@ -1306,13 +1312,14 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
{
if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
- QDeclarativeListReferencePrivate *p = QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
+ QDeclarativeListReferencePrivate *p =
+ QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
if (p->object) {
return listClass->newList(p->property, p->propertyType);
} else {
return scriptEngine.nullValue();
}
- }
+ }
bool objOk;
QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
@@ -1405,7 +1412,9 @@ struct QDeclarativeEnginePrivate::ImportedNamespace {
foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) {
if (c.typeName == typeName) {
typeWasDeclaredInQmldir = true;
- if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) {
+
+ // importing version -1 means import ALL versions
+ if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) {
QUrl candidate = url.resolved(QUrl(c.fileName));
if (c.internal && base) {
if (base->resolved(QUrl(c.fileName)) != candidate)
@@ -1454,13 +1463,14 @@ public:
QDeclarativeDirComponents importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) {
QFile file(absoluteFilePath);
- QString dir = QFileInfo(file).path();
QString filecontent;
if (file.open(QFile::ReadOnly)) {
filecontent = QString::fromUtf8(file.readAll());
if (qmlImportTrace())
qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath;
}
+ QDir dir = QFileInfo(file).dir();
+
QDeclarativeDirParser qmldirParser;
qmldirParser.setSource(filecontent);
qmldirParser.parse();
@@ -1470,9 +1480,13 @@ public:
foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
- QDir pluginDir(dir + QDir::separator() + plugin.path);
- if (dir.startsWith(QLatin1Char(':')))
+
+ 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,
@@ -1492,29 +1506,7 @@ public:
if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\')))
dir.chop(1);
- QStringList paths;
-
- if (!base.isEmpty()) {
- QString baseDir = QFileInfo(toLocalFileOrQrc(base)).path();
- paths += baseDir;
- }
-
- QString applicationDirPath = QCoreApplication::applicationDirPath();
- if (!applicationDirPath.isEmpty())
- paths += applicationDirPath;
-
- paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath;
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
-#else
- QString builtinPath;
-#endif
- if (!builtinPath.isEmpty())
- paths += builtinPath;
-
- // add fileImportPath last, this is *not* search order.
- paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath;
-
+ QStringList paths = QDeclarativeEnginePrivate::get(engine)->fileImportPath;
qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents.
QString stableRelativePath = dir;
@@ -1554,28 +1546,8 @@ public:
QString dir;
- // user import paths
- QStringList paths;
- // base..
- QString localFileOrQrc = toLocalFileOrQrc(base);
- QString localFileOrQrcPath = QFileInfo(localFileOrQrc).path();
- paths += localFileOrQrcPath;
- paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath;
-
- QString applicationDirPath = QCoreApplication::applicationDirPath();
- if (!applicationDirPath.isEmpty())
- paths += applicationDirPath;
-
- paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath;
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
-#else
- QString builtinPath;
-#endif
- if (!builtinPath.isEmpty())
- paths += builtinPath;
-
- foreach (const QString &p, paths) {
+ foreach (const QString &p,
+ QDeclarativeEnginePrivate::get(engine)->fileImportPath) {
dir = p+QLatin1Char('/')+url;
QFileInfo fi(dir+QLatin1String("/qmldir"));
@@ -1807,18 +1779,9 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const
Adds \a path as a directory where installed QML components are
defined in a URL-based directory structure.
- For example, if you add \c /opt/MyApp/lib/imports and then load QML
- that imports \c com.mycompany.Feature, then QDeclarativeEngine will look
- in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
- provided by that module. A \c qmldir file is required for definiting the
- type version mapping and possibly declarative extensions plugins.
-
- The engine searches in the base directory of the qml file, then
- the paths added via addImportPath(), then in the directory containing the
- application executable (QCoreApplication::applicationDirPath()),
- then the paths specified in the \c QML_IMPORT_PATH environment variable, then the
- builtin \c ImportsPath from QLibraryInfo.
+ The newly added \a path will be first in the importPathList().
+ \sa setImportPathList()
*/
void QDeclarativeEngine::addImportPath(const QString& path)
{
@@ -1828,6 +1791,43 @@ void QDeclarativeEngine::addImportPath(const QString& path)
d->fileImportPath.prepend(path);
}
+
+/*!
+ Returns the list of directories where the engine searches for
+ installed modules.
+
+ 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
+ in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
+ provided by that module. A \c qmldir file is required for defining the
+ type version mapping and possibly declarative extensions plugins.
+
+ By default, the list contains the paths specified in the \c QML_IMPORT_PATH environment
+ variable, then the builtin \c ImportsPath from QLibraryInfo.
+
+ \sa addImportPath() setImportPathList()
+*/
+QStringList QDeclarativeEngine::importPathList() const
+{
+ Q_D(const QDeclarativeEngine);
+ return d->fileImportPath;
+}
+
+/*!
+ Sets the list of directories where the engine searches for
+ installed modules.
+
+ By default, the list contains the paths specified in the \c QML_IMPORT_PATH environment
+ variable, then the builtin \c ImportsPath from QLibraryInfo.
+
+ \sa importPathList() addImportPath()
+ */
+void QDeclarativeEngine::setImportPathList(const QStringList &paths)
+{
+ Q_D(QDeclarativeEngine);
+ d->fileImportPath = paths;
+}
+
/*!
Imports the extension named \a fileName from the \a uri provided.
Returns true if the extension was successfully imported.
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index 19e81b6..b861c1b 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -77,7 +77,10 @@ public:
void clearComponentCache();
+ QStringList importPathList() const;
+ void setImportPathList(const QStringList &paths);
void addImportPath(const QString& dir);
+
bool importExtension(const QString &fileName, const QString &uri);
void setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *);
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index 06b5027..5aff30d 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -225,7 +225,7 @@ public:
mutable QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory;
QHash<QString,QDeclarativeImageProvider*> imageProviders;
- QImage getImageFromProvider(const QUrl &url);
+ QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
mutable QMutex mutex;
@@ -272,7 +272,6 @@ public:
};
- QStringList environmentImportPath;
QSet<QString> initializedPlugins;
QString resolvePlugin(const QDir &dir, const QString &baseName,
diff --git a/src/declarative/qml/qdeclarativefastproperties.cpp b/src/declarative/qml/qdeclarativefastproperties.cpp
new file mode 100644
index 0000000..088d329
--- /dev/null
+++ b/src/declarative/qml/qdeclarativefastproperties.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qdeclarativefastproperties_p.h"
+
+#include <private/qdeclarativeitem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// Adding entries to the QDeclarativeFastProperties class allows the QML
+// binding optimizer to bypass Qt's meta system and read and, more
+// importantly, subscribe to properties directly. Any property that is
+// primarily read from bindings is a candidate for inclusion as a fast
+// property.
+
+QDeclarativeFastProperties::QDeclarativeFastProperties()
+{
+ add(&QDeclarativeItem::staticMetaObject, QDeclarativeItem::staticMetaObject.indexOfProperty("parent"),
+ QDeclarativeItemPrivate::parentProperty);
+}
+
+int QDeclarativeFastProperties::accessorIndexForProperty(const QMetaObject *metaObject, int propertyIndex)
+{
+ Q_ASSERT(metaObject);
+ Q_ASSERT(propertyIndex >= 0);
+
+ // Find the "real" metaObject
+ while (metaObject->propertyOffset() > propertyIndex)
+ metaObject = metaObject->superClass();
+
+ QHash<QPair<const QMetaObject *, int>, int>::Iterator iter =
+ m_index.find(qMakePair(metaObject, propertyIndex));
+ if (iter != m_index.end())
+ return *iter;
+ else
+ return -1;
+}
+
+void QDeclarativeFastProperties::add(const QMetaObject *metaObject, int propertyIndex, Accessor accessor)
+{
+ Q_ASSERT(metaObject);
+ Q_ASSERT(propertyIndex >= 0);
+
+ // Find the "real" metaObject
+ while (metaObject->propertyOffset() > propertyIndex)
+ metaObject = metaObject->superClass();
+
+ QPair<const QMetaObject *, int> data = qMakePair(metaObject, propertyIndex);
+ int accessorIndex = m_accessors.count();
+ m_accessors.append(accessor);
+ m_index.insert(data, accessorIndex);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativescript.cpp b/src/declarative/qml/qdeclarativefastproperties_p.h
index ac4b2c1..60df947 100644
--- a/src/declarative/qml/qdeclarativescript.cpp
+++ b/src/declarative/qml/qdeclarativefastproperties_p.h
@@ -39,50 +39,37 @@
**
****************************************************************************/
-// This is just a dummy file to include the documentation
+#ifndef QDECLARATIVEFASTPROPERTIES_P_H
+#define QDECLARATIVEFASTPROPERTIES_P_H
-/*!
- \qmlclass Script QDeclarativeScript
- \since 4.7
- \brief The Script element provides a way to add JavaScript code snippets in QML.
- \ingroup group_utility
+#include <QtCore/qvector.h>
+#include <QtCore/qhash.h>
- The Script element is used to add convenient JavaScript "glue" methods to
- your Qt Declarative application or component.
+QT_BEGIN_HEADER
- An example:
+QT_BEGIN_NAMESPACE
- \qml
- Script {
- function debugMyComponent() {
- console.log(text.text);
- console.log(otherinterestingitem.property);
- }
- }
- MouseArea { onClicked: debugMyComponent() }
- \endqml
+class QObject;
+class QDeclarativeNotifierEndpoint;
+class QDeclarativeFastProperties
+{
+public:
+ typedef void (*Accessor)(QObject *object, void *output, QDeclarativeNotifierEndpoint *endpoint);
- \note While it is possible to use any JavaScript code within a Script element,
- it is recommended that the code be limited to defining functions. The Script
- element executes JavaScript as soon as it is specified, so
- when defining a component, this may be done before the execution context is
- fully specified. As a result, some properties or items may not be
- accessible. You can avoid this problem by limiting your JavaScript to
- defining functions that are only executed later once the context is fully
- defined.
+ QDeclarativeFastProperties();
- \sa {JavaScript Blocks}
-*/
+ Accessor accessor(int index) const { return m_accessors.at(index); }
+ int accessorIndexForProperty(const QMetaObject *, int);
-/*!
- \qmlproperty string Script::script
- \default
- The JavaScript code to be executed.
-*/
+private:
+ void add(const QMetaObject *, int, Accessor);
-/*!
- \qmlproperty url Script::source
+ QHash<QPair<const QMetaObject *, int>, int> m_index;
+ QVector<Accessor> m_accessors;
+};
- Specifies a source file containing JavaScript code. This can be used instead
- of providing inline JavaScript code in the Script element.
-*/
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEFASTPROPERTIES_P_H
diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp
index 9ef8545..b992b9f 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.cpp
+++ b/src/declarative/qml/qdeclarativeimageprovider.cpp
@@ -61,10 +61,14 @@ QDeclarativeImageProvider::~QDeclarativeImageProvider()
}
/*!
- \fn QImage QDeclarativeImageProvider::request(const QString &id)
+ \fn QImage QDeclarativeImageProvider::request(const QString &id, QSize *size, const QSize& requested_size)
Implement this method to return the image with \a id.
+ If \a requested_size is a valid size, resize the image to that size before returning.
+
+ In any case, \a size must be set to the (original) size of the image.
+
Note: this method may be called by multiple threads, so ensure the
implementation of this method is reentrant.
*/
diff --git a/src/declarative/qml/qdeclarativeimageprovider.h b/src/declarative/qml/qdeclarativeimageprovider.h
index 6ee7bcf..50b73fe 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.h
+++ b/src/declarative/qml/qdeclarativeimageprovider.h
@@ -54,7 +54,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeImageProvider
{
public:
virtual ~QDeclarativeImageProvider();
- virtual QImage request(const QString &id) = 0;
+ virtual QImage request(const QString &id, QSize *size, const QSize& requested_size) = 0;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativelist.h b/src/declarative/qml/qdeclarativelist.h
index ed402a8..219aa4b 100644
--- a/src/declarative/qml/qdeclarativelist.h
+++ b/src/declarative/qml/qdeclarativelist.h
@@ -54,8 +54,12 @@ QT_MODULE(Declarative)
class QObject;
struct QMetaObject;
+
+#ifndef QDECLARATIVELISTPROPERTY
+#define QDECLARATIVELISTPROPERTY
template<typename T>
-struct QDeclarativeListProperty {
+class QDeclarativeListProperty {
+public:
typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*);
typedef int (*CountFunction)(QDeclarativeListProperty<T> *);
typedef T *(*AtFunction)(QDeclarativeListProperty<T> *, int);
@@ -106,6 +110,7 @@ private:
return ((QList<T *> *)p->data)->clear();
}
};
+#endif
class QDeclarativeEngine;
class QDeclarativeListReferencePrivate;
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index 476b027..f432024 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -203,7 +203,7 @@ namespace QDeclarativeParser
DynamicProperty();
DynamicProperty(const DynamicProperty &);
- enum Type { Variant, Int, Bool, Real, String, Url, Color, Date, Alias, Custom, CustomList };
+ enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, Date, DateTime, Alias, Custom, CustomList };
bool isDefaultProperty;
Type type;
diff --git a/src/declarative/qml/qdeclarativeproperty.h b/src/declarative/qml/qdeclarativeproperty.h
index 73bccf3..8f6ea48 100644
--- a/src/declarative/qml/qdeclarativeproperty.h
+++ b/src/declarative/qml/qdeclarativeproperty.h
@@ -131,6 +131,11 @@ private:
};
typedef QList<QDeclarativeProperty> QDeclarativeProperties;
+inline uint qHash (const QDeclarativeProperty &key)
+{
+ return qHash(key.object()) + qHash(key.name());
+}
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index 49bd3b7..9fff294 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -528,9 +528,14 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
{ "string", Object::DynamicProperty::String, "QString" },
{ "url", Object::DynamicProperty::Url, "QUrl" },
{ "color", Object::DynamicProperty::Color, "QColor" },
- { "date", Object::DynamicProperty::Date, "QDate" },
- { "var", Object::DynamicProperty::Variant, "QVariant" },
- { "variant", Object::DynamicProperty::Variant, "QVariant" }
+ // Internally QTime, QDate and QDateTime are all supported.
+ // To be more consistent with JavaScript we expose only
+ // QDateTime as it matches closely with the Date JS type.
+ // We also call it "date" to match.
+ // { "time", Object::DynamicProperty::Time, "QTime" },
+ // { "date", Object::DynamicProperty::Date, "QDate" },
+ { "date", Object::DynamicProperty::DateTime, "QDateTime" },
+ { "var", Object::DynamicProperty::Variant, "QVariant" }
};
const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
sizeof(propTypeNameToTypes[0]);
diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp
index 2d5f096..37d2d5b 100644
--- a/src/declarative/qml/qdeclarativesqldatabase.cpp
+++ b/src/declarative/qml/qdeclarativesqldatabase.cpp
@@ -279,7 +279,7 @@ static QScriptValue qmlsqldatabase_change_version(QScriptContext *context, QScri
QString foundvers = context->thisObject().property(QLatin1String("version")).toString();
if (from_version!=foundvers) {
- THROW_SQL(2,QDeclarativeEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(foundvers));
+ THROW_SQL(VERSION_ERR,QDeclarativeEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(foundvers));
return engine->undefinedValue();
}
@@ -293,7 +293,7 @@ static QScriptValue qmlsqldatabase_change_version(QScriptContext *context, QScri
} else {
if (!db.commit()) {
db.rollback();
- THROW_SQL(0,QDeclarativeEngine::tr("SQL transaction failed"));
+ THROW_SQL(UNKNOWN_ERR,QDeclarativeEngine::tr("SQL transaction failed"));
} else {
ok = true;
}
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index f9c99ee..9a7bdd6 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -47,19 +47,340 @@
#include "qdeclarativeexpression_p.h"
#include "qdeclarativecontext_p.h"
-#include <QColor>
-#include <QDate>
-#include <QtCore/qlist.h>
-#include <QtCore/qdebug.h>
+Q_DECLARE_METATYPE(QScriptValue);
QT_BEGIN_NAMESPACE
+class QDeclarativeVMEVariant
+{
+public:
+ inline QDeclarativeVMEVariant();
+ inline ~QDeclarativeVMEVariant();
+
+ inline const void *dataPtr() const;
+ inline void *dataPtr();
+ inline int dataType() const;
+
+ inline QObject *asQObject();
+ inline const QVariant &asQVariant();
+ inline int asInt();
+ inline bool asBool();
+ inline double asDouble();
+ inline const QString &asQString();
+ inline const QUrl &asQUrl();
+ inline const QColor &asQColor();
+ inline const QTime &asQTime();
+ inline const QDate &asQDate();
+ inline const QDateTime &asQDateTime();
+ inline const QScriptValue &asQScriptValue();
+
+ inline void setValue(QObject *);
+ inline void setValue(const QVariant &);
+ inline void setValue(int);
+ inline void setValue(bool);
+ inline void setValue(double);
+ inline void setValue(const QString &);
+ inline void setValue(const QUrl &);
+ inline void setValue(const QColor &);
+ inline void setValue(const QTime &);
+ inline void setValue(const QDate &);
+ inline void setValue(const QDateTime &);
+ inline void setValue(const QScriptValue &);
+
+private:
+ int type;
+ void *data[4]; // Large enough to hold all types
+
+ inline void cleanup();
+};
+
+QDeclarativeVMEVariant::QDeclarativeVMEVariant()
+: type(QVariant::Invalid)
+{
+}
+
+QDeclarativeVMEVariant::~QDeclarativeVMEVariant()
+{
+ cleanup();
+}
+
+void QDeclarativeVMEVariant::cleanup()
+{
+ if (type == QVariant::Invalid) {
+ } else if (type == QMetaType::QObjectStar ||
+ type == QMetaType::Int ||
+ type == QMetaType::Bool ||
+ type == QMetaType::Double) {
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QString) {
+ ((QString *)dataPtr())->~QString();
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QUrl) {
+ ((QUrl *)dataPtr())->~QUrl();
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QColor) {
+ ((QColor *)dataPtr())->~QColor();
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QTime) {
+ ((QTime *)dataPtr())->~QTime();
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QDate) {
+ ((QDate *)dataPtr())->~QDate();
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QDateTime) {
+ ((QDateTime *)dataPtr())->~QDateTime();
+ type = QVariant::Invalid;
+ } else if (type == qMetaTypeId<QVariant>()) {
+ ((QVariant *)dataPtr())->~QVariant();
+ type = QVariant::Invalid;
+ } else if (type == qMetaTypeId<QScriptValue>()) {
+ ((QScriptValue *)dataPtr())->~QScriptValue();
+ type = QVariant::Invalid;
+ }
+
+}
+
+int QDeclarativeVMEVariant::dataType() const
+{
+ return type;
+}
+
+const void *QDeclarativeVMEVariant::dataPtr() const
+{
+ return &data;
+}
+
+void *QDeclarativeVMEVariant::dataPtr()
+{
+ return &data;
+}
+
+QObject *QDeclarativeVMEVariant::asQObject()
+{
+ if (type != QMetaType::QObjectStar)
+ setValue((QObject *)0);
+
+ return *(QObject **)(dataPtr());
+}
+
+const QVariant &QDeclarativeVMEVariant::asQVariant()
+{
+ if (type != QMetaType::QVariant)
+ setValue(QVariant());
+
+ return *(QVariant *)(dataPtr());
+}
+
+int QDeclarativeVMEVariant::asInt()
+{
+ if (type != QMetaType::Int)
+ setValue(int(0));
+
+ return *(int *)(dataPtr());
+}
+
+bool QDeclarativeVMEVariant::asBool()
+{
+ if (type != QMetaType::Bool)
+ setValue(bool(false));
+
+ return *(bool *)(dataPtr());
+}
+
+double QDeclarativeVMEVariant::asDouble()
+{
+ if (type != QMetaType::Double)
+ setValue(double(0));
+
+ return *(double *)(dataPtr());
+}
+
+const QString &QDeclarativeVMEVariant::asQString()
+{
+ if (type != QMetaType::QString)
+ setValue(QString());
+
+ return *(QString *)(dataPtr());
+}
+
+const QUrl &QDeclarativeVMEVariant::asQUrl()
+{
+ if (type != QMetaType::QUrl)
+ setValue(QUrl());
+
+ return *(QUrl *)(dataPtr());
+}
+
+const QColor &QDeclarativeVMEVariant::asQColor()
+{
+ if (type != QMetaType::QColor)
+ setValue(QColor());
+
+ return *(QColor *)(dataPtr());
+}
+
+const QTime &QDeclarativeVMEVariant::asQTime()
+{
+ if (type != QMetaType::QTime)
+ setValue(QTime());
+
+ return *(QTime *)(dataPtr());
+}
+
+const QDate &QDeclarativeVMEVariant::asQDate()
+{
+ if (type != QMetaType::QDate)
+ setValue(QDate());
+
+ return *(QDate *)(dataPtr());
+}
+
+const QDateTime &QDeclarativeVMEVariant::asQDateTime()
+{
+ if (type != QMetaType::QDateTime)
+ setValue(QDateTime());
+
+ return *(QDateTime *)(dataPtr());
+}
+
+const QScriptValue &QDeclarativeVMEVariant::asQScriptValue()
+{
+ if (type != qMetaTypeId<QScriptValue>())
+ setValue(QScriptValue());
+
+ return *(QScriptValue *)(dataPtr());
+}
+
+void QDeclarativeVMEVariant::setValue(QObject *v)
+{
+ if (type != QMetaType::QObjectStar) {
+ cleanup();
+ type = QMetaType::QObjectStar;
+ }
+ *(QObject **)(dataPtr()) = v;
+}
+
+void QDeclarativeVMEVariant::setValue(const QVariant &v)
+{
+ if (type != qMetaTypeId<QVariant>()) {
+ cleanup();
+ type = qMetaTypeId<QVariant>();
+ new (dataPtr()) QVariant(v);
+ } else {
+ *(QVariant *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(int v)
+{
+ if (type != QMetaType::Int) {
+ cleanup();
+ type = QMetaType::Int;
+ }
+ *(int *)(dataPtr()) = v;
+}
+
+void QDeclarativeVMEVariant::setValue(bool v)
+{
+ if (type != QMetaType::Bool) {
+ cleanup();
+ type = QMetaType::Bool;
+ }
+ *(bool *)(dataPtr()) = v;
+}
+
+void QDeclarativeVMEVariant::setValue(double v)
+{
+ if (type != QMetaType::Double) {
+ cleanup();
+ type = QMetaType::Double;
+ }
+ *(double *)(dataPtr()) = v;
+}
+
+void QDeclarativeVMEVariant::setValue(const QString &v)
+{
+ if (type != QMetaType::QString) {
+ cleanup();
+ type = QMetaType::QString;
+ new (dataPtr()) QString(v);
+ } else {
+ *(QString *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(const QUrl &v)
+{
+ if (type != QMetaType::QUrl) {
+ cleanup();
+ type = QMetaType::QUrl;
+ new (dataPtr()) QUrl(v);
+ } else {
+ *(QUrl *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(const QColor &v)
+{
+ if (type != QMetaType::QColor) {
+ cleanup();
+ type = QMetaType::QColor;
+ new (dataPtr()) QColor(v);
+ } else {
+ *(QColor *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(const QTime &v)
+{
+ if (type != QMetaType::QTime) {
+ cleanup();
+ type = QMetaType::QTime;
+ new (dataPtr()) QTime(v);
+ } else {
+ *(QTime *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(const QDate &v)
+{
+ if (type != QMetaType::QDate) {
+ cleanup();
+ type = QMetaType::QDate;
+ new (dataPtr()) QDate(v);
+ } else {
+ *(QDate *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(const QDateTime &v)
+{
+ if (type != QMetaType::QDateTime) {
+ cleanup();
+ type = QMetaType::QDateTime;
+ new (dataPtr()) QDateTime(v);
+ } else {
+ *(QDateTime *)(dataPtr()) = v;
+ }
+}
+
+void QDeclarativeVMEVariant::setValue(const QScriptValue &v)
+{
+ if (type != qMetaTypeId<QScriptValue>()) {
+ cleanup();
+ type = qMetaTypeId<QScriptValue>();
+ new (dataPtr()) QScriptValue(v);
+ } else {
+ *(QScriptValue *)(dataPtr()) = v;
+ }
+}
+
QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
const QMetaObject *other,
const QDeclarativeVMEMetaData *meta,
QDeclarativeCompiledData *cdata)
: object(obj), compiledData(cdata), ctxt(QDeclarativeDeclarativeData::get(obj)->outerContext),
- metaData(meta), methods(0), parent(0)
+ metaData(meta), data(0), methods(0), parent(0)
{
compiledData->addref();
@@ -74,20 +395,18 @@ QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
propOffset = QAbstractDynamicMetaObject::propertyOffset();
methodOffset = QAbstractDynamicMetaObject::methodOffset();
- data = new QVariant[metaData->propertyCount];
- aConnected.resize(metaData->aliasCount);
+ data = new QDeclarativeVMEVariant[metaData->propertyCount];
+ aConnected.resize(metaData->aliasCount);
int list_type = qMetaTypeId<QDeclarativeListProperty<QObject> >();
+
// ### Optimize
for (int ii = 0; ii < metaData->propertyCount; ++ii) {
int t = (metaData->propertyData() + ii)->propertyType;
if (t == list_type) {
- listProperties.append(new List(methodOffset + ii));
- data[ii] = QVariant::fromValue(QDeclarativeListProperty<QObject>(obj, listProperties.last(), list_append,
- list_count, list_at, list_clear));
- } else if (t != -1) {
- data[ii] = QVariant((QVariant::Type)t);
- }
+ listProperties.append(List(methodOffset + ii));
+ data[ii].setValue(listProperties.count() - 1);
+ }
}
}
@@ -95,7 +414,6 @@ QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject()
{
compiledData->release();
delete parent;
- qDeleteAll(listProperties);
delete [] data;
delete [] methods;
}
@@ -145,11 +463,10 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (t == -1) {
if (c == QMetaObject::ReadProperty) {
- *reinterpret_cast<QVariant *>(a[0]) = data[id];
+ *reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id);
} else if (c == QMetaObject::WriteProperty) {
- needActivate =
- (data[id] != *reinterpret_cast<QVariant *>(a[0]));
- data[id] = *reinterpret_cast<QVariant *>(a[0]);
+ needActivate = (data[id].asQVariant() != *reinterpret_cast<QVariant *>(a[0]));
+ data[id].setValue(*reinterpret_cast<QVariant *>(a[0]));
}
} else {
@@ -157,42 +474,86 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (c == QMetaObject::ReadProperty) {
switch(t) {
case QVariant::Int:
- *reinterpret_cast<int *>(a[0]) = data[id].toInt();
+ *reinterpret_cast<int *>(a[0]) = data[id].asInt();
break;
case QVariant::Bool:
- *reinterpret_cast<bool *>(a[0]) = data[id].toBool();
+ *reinterpret_cast<bool *>(a[0]) = data[id].asBool();
break;
case QVariant::Double:
- *reinterpret_cast<double *>(a[0]) = data[id].toDouble();
+ *reinterpret_cast<double *>(a[0]) = data[id].asDouble();
break;
case QVariant::String:
- *reinterpret_cast<QString *>(a[0]) = data[id].toString();
+ *reinterpret_cast<QString *>(a[0]) = data[id].asQString();
break;
case QVariant::Url:
- *reinterpret_cast<QUrl *>(a[0]) = data[id].toUrl();
+ *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl();
break;
case QVariant::Color:
- *reinterpret_cast<QColor *>(a[0]) = data[id].value<QColor>();
+ *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor();
break;
case QVariant::Date:
- *reinterpret_cast<QDate *>(a[0]) = data[id].toDate();
+ *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate();
+ break;
+ case QVariant::DateTime:
+ *reinterpret_cast<QDateTime *>(a[0]) = data[id].asQDateTime();
break;
case QMetaType::QObjectStar:
- *reinterpret_cast<QObject **>(a[0]) = data[id].value<QObject*>();
+ *reinterpret_cast<QObject **>(a[0]) = data[id].asQObject();
break;
default:
break;
}
if (t == qMetaTypeId<QDeclarativeListProperty<QObject> >()) {
+ int listIndex = data[id].asInt();
+ const List *list = &listProperties.at(listIndex);
*reinterpret_cast<QDeclarativeListProperty<QObject> *>(a[0]) =
- data[id].value<QDeclarativeListProperty<QObject> >();
+ QDeclarativeListProperty<QObject>(object, (void *)list,
+ list_append, list_count, list_at,
+ list_clear);
}
} else if (c == QMetaObject::WriteProperty) {
- QVariant value = QVariant((QVariant::Type)data[id].type(), a[0]);
- needActivate = (data[id] != value);
- data[id] = value;
+ switch(t) {
+ case QVariant::Int:
+ needActivate = *reinterpret_cast<int *>(a[0]) != data[id].asInt();
+ data[id].setValue(*reinterpret_cast<int *>(a[0]));
+ break;
+ case QVariant::Bool:
+ needActivate = *reinterpret_cast<bool *>(a[0]) != data[id].asBool();
+ data[id].setValue(*reinterpret_cast<bool *>(a[0]));
+ break;
+ case QVariant::Double:
+ needActivate = *reinterpret_cast<double *>(a[0]) != data[id].asDouble();
+ data[id].setValue(*reinterpret_cast<double *>(a[0]));
+ break;
+ case QVariant::String:
+ needActivate = *reinterpret_cast<QString *>(a[0]) != data[id].asQString();
+ data[id].setValue(*reinterpret_cast<QString *>(a[0]));
+ break;
+ case QVariant::Url:
+ needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl();
+ data[id].setValue(*reinterpret_cast<QUrl *>(a[0]));
+ break;
+ case QVariant::Color:
+ needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor();
+ data[id].setValue(*reinterpret_cast<QColor *>(a[0]));
+ break;
+ case QVariant::Date:
+ needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate();
+ data[id].setValue(*reinterpret_cast<QDate *>(a[0]));
+ break;
+ case QVariant::DateTime:
+ needActivate = *reinterpret_cast<QDateTime *>(a[0]) != data[id].asQDateTime();
+ data[id].setValue(*reinterpret_cast<QDateTime *>(a[0]));
+ break;
+ case QMetaType::QObjectStar:
+ needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject();
+ data[id].setValue(*reinterpret_cast<QObject **>(a[0]));
+ break;
+ default:
+ break;
+ }
}
}
@@ -316,6 +677,28 @@ QScriptValue QDeclarativeVMEMetaObject::method(int index)
return methods[index];
}
+QScriptValue QDeclarativeVMEMetaObject::readVarProperty(int id)
+{
+ if (data[id].dataType() == qMetaTypeId<QScriptValue>())
+ return data[id].asQScriptValue();
+ else
+ return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueFromVariant(data[id].asQVariant());
+}
+
+QVariant QDeclarativeVMEMetaObject::readVarPropertyAsVariant(int id)
+{
+ if (data[id].dataType() == qMetaTypeId<QScriptValue>())
+ return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueToVariant(data[id].asQScriptValue());
+ else
+ return data[id].asQVariant();
+}
+
+void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &value)
+{
+ data[id].setValue(value);
+ activate(object, methodOffset + id, 0);
+}
+
void QDeclarativeVMEMetaObject::listChanged(int id)
{
activate(object, methodOffset + id, 0);
@@ -364,4 +747,22 @@ QScriptValue QDeclarativeVMEMetaObject::vmeMethod(int index)
return method(index - methodOffset - plainSignals);
}
+QScriptValue QDeclarativeVMEMetaObject::vmeProperty(int index)
+{
+ if (index < propOffset) {
+ Q_ASSERT(parent);
+ return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeProperty(index);
+ }
+ return readVarProperty(index - propOffset);
+}
+
+void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v)
+{
+ if (index < propOffset) {
+ Q_ASSERT(parent);
+ static_cast<QDeclarativeVMEMetaObject *>(parent)->setVMEProperty(index, v);
+ }
+ return writeVarProperty(index - propOffset, v);
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index e11f6fa..839f0cd 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -58,6 +58,10 @@
#include <QtCore/QMetaObject>
#include <QtCore/QBitArray>
#include <QtCore/QPair>
+#include <QtGui/QColor>
+#include <QtCore/QDate>
+#include <QtCore/qlist.h>
+#include <QtCore/qdebug.h>
#include <private/qobject_p.h>
@@ -106,6 +110,7 @@ struct QDeclarativeVMEMetaData
}
};
+class QDeclarativeVMEVariant;
class QDeclarativeRefCount;
class QDeclarativeVMEMetaObject : public QAbstractDynamicMetaObject
{
@@ -116,6 +121,9 @@ public:
void registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor);
QScriptValue vmeMethod(int index);
+ QScriptValue vmeProperty(int index);
+ void setVMEProperty(int index, const QScriptValue &);
+
protected:
virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
@@ -128,7 +136,8 @@ private:
int propOffset;
int methodOffset;
- QVariant *data;
+ QDeclarativeVMEVariant *data;
+
QBitArray aConnected;
QBitArray aInterceptors;
QHash<int, QPair<int, QDeclarativePropertyValueInterceptor*> > interceptors;
@@ -136,6 +145,10 @@ private:
QScriptValue *methods;
QScriptValue method(int);
+ QScriptValue readVarProperty(int);
+ QVariant readVarPropertyAsVariant(int);
+ void writeVarProperty(int, const QScriptValue &);
+
QAbstractDynamicMetaObject *parent;
void listChanged(int);
@@ -145,7 +158,7 @@ private:
List(int lpi) : notifyIndex(lpi) {}
int notifyIndex;
};
- QList<List *> listProperties;
+ QList<List> listProperties;
static void list_append(QDeclarativeListProperty<QObject> *, QObject *);
static int list_count(QDeclarativeListProperty<QObject> *);
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index a7ed358..628681f 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -437,8 +437,12 @@ QDeclarativeWorkerScriptEngine::QDeclarativeWorkerScriptEngine(QDeclarativeEngin
QDeclarativeWorkerScriptEngine::~QDeclarativeWorkerScriptEngine()
{
+ d->m_lock.lock();
qDeleteAll(d->workers);
- delete d; d = 0;
+ d->workers.clear();
+ d->m_lock.unlock();
+
+ d->deleteLater();
}
QDeclarativeWorkerScriptEnginePrivate::WorkerScript::WorkerScript()
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 49888c3..e2f0c67 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -31,11 +31,11 @@ SOURCES += \
$$PWD/qdeclarativerewrite.cpp \
$$PWD/qdeclarativevaluetype.cpp \
$$PWD/qdeclarativecompiledbindings.cpp \
+ $$PWD/qdeclarativefastproperties.cpp \
$$PWD/qdeclarativexmlhttprequest.cpp \
$$PWD/qdeclarativesqldatabase.cpp \
$$PWD/qmetaobjectbuilder.cpp \
$$PWD/qdeclarativewatcher.cpp \
- $$PWD/qdeclarativescript.cpp \
$$PWD/qdeclarativecleanup.cpp \
$$PWD/qdeclarativepropertycache.cpp \
$$PWD/qdeclarativenotifier.cpp \
@@ -103,6 +103,7 @@ HEADERS += \
$$PWD/qbitfield_p.h \
$$PWD/qdeclarativevaluetype_p.h \
$$PWD/qdeclarativecompiledbindings_p.h \
+ $$PWD/qdeclarativefastproperties_p.h \
$$PWD/qdeclarativexmlhttprequest_p.h \
$$PWD/qdeclarativesqldatabase_p.h \
$$PWD/qmetaobjectbuilder_p.h \