summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorJanne Koskinen <janne.p.koskinen@digia.com>2010-04-23 14:08:48 (GMT)
committerJanne Koskinen <janne.p.koskinen@digia.com>2010-04-23 14:08:48 (GMT)
commitfecce960a050ef2964e28f373bf1a35f7d9949a3 (patch)
tree296ef35071a80076a5186e71696cddc88cc1a56f /src/declarative/qml
parent02c65146610cdd5bfe1f3ee4656ba07af82afcc7 (diff)
parent15088d236924bccee787953e04214f87392e8e55 (diff)
downloadQt-fecce960a050ef2964e28f373bf1a35f7d9949a3.zip
Qt-fecce960a050ef2964e28f373bf1a35f7d9949a3.tar.gz
Qt-fecce960a050ef2964e28f373bf1a35f7d9949a3.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-webkit into 4.7
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/parser/qdeclarativejs.g2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsgrammar.cpp6
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp150
-rw-r--r--src/declarative/qml/qdeclarative.h14
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp11
-rw-r--r--src/declarative/qml/qdeclarativeboundsignal.cpp12
-rw-r--r--src/declarative/qml/qdeclarativeboundsignal_p.h5
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp9
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp146
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp50
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h4
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager.cpp1
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp50
-rw-r--r--src/declarative/qml/qdeclarativecontext.h1
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecontextscriptclass.cpp8
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp20
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h4
-rw-r--r--src/declarative/qml/qdeclarativedata_p.h3
-rw-r--r--src/declarative/qml/qdeclarativedirparser.cpp9
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp309
-rw-r--r--src/declarative/qml/qdeclarativeengine.h8
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h10
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp4
-rw-r--r--src/declarative/qml/qdeclarativeerror.cpp63
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp29
-rw-r--r--src/declarative/qml/qdeclarativeexpression.h7
-rw-r--r--src/declarative/qml/qdeclarativeexpression_p.h1
-rw-r--r--src/declarative/qml/qdeclarativeextensionplugin.cpp11
-rw-r--r--src/declarative/qml/qdeclarativeextensionplugin.h3
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.cpp22
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.h2
-rw-r--r--src/declarative/qml/qdeclarativeinfo.cpp124
-rw-r--r--src/declarative/qml/qdeclarativeinfo.h21
-rw-r--r--src/declarative/qml/qdeclarativeinstruction.cpp3
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h1
-rw-r--r--src/declarative/qml/qdeclarativelist.cpp15
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp122
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h1
-rw-r--r--src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp11
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp36
-rw-r--r--src/declarative/qml/qdeclarativeparser.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeparserstatus.cpp32
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h1
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp1
-rw-r--r--src/declarative/qml/qdeclarativepropertyvaluesource.cpp6
-rw-r--r--src/declarative/qml/qdeclarativeproxymetaobject.cpp14
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp100
-rw-r--r--src/declarative/qml/qdeclarativescriptstring.cpp33
-rw-r--r--src/declarative/qml/qdeclarativetypenotavailable.cpp49
-rw-r--r--src/declarative/qml/qdeclarativetypenotavailable_p.h65
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp10
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp7
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp27
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h1
-rw-r--r--src/declarative/qml/qdeclarativewatcher.cpp2
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp2
-rw-r--r--src/declarative/qml/qml.pri2
60 files changed, 1048 insertions, 622 deletions
diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g
index ba9338e..1b66ba0 100644
--- a/src/declarative/qml/parser/qdeclarativejs.g
+++ b/src/declarative/qml/parser/qdeclarativejs.g
@@ -1376,7 +1376,7 @@ case $rule_number: {
} break;
./
-PropertyName: T_IDENTIFIER %prec REDUCE_HERE ;
+PropertyName: T_IDENTIFIER %prec SHIFT_THERE ;
/.
case $rule_number: {
AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
index 52e979a..b87d8f4 100644
--- a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
// This file was generated by qlalr - DO NOT EDIT!
-#include "private/qdeclarativejsgrammar_p.h"
+#include "qdeclarativejsgrammar_p.h"
QT_BEGIN_NAMESPACE
@@ -346,9 +346,9 @@ const short QDeclarativeJSGrammar::action_index [] = {
const short QDeclarativeJSGrammar::action_info [] = {
399, 352, 345, -101, 343, 457, 440, 403, 257, -112,
- -125, -131, -123, -98, -120, 348, -128, 389, 453, 391,
+ -125, -131, -123, 346, -120, 348, -128, 389, 453, 391,
416, 401, 408, 563, -101, -123, 416, -120, 539, -131,
- -98, -112, -125, 348, 257, 99, 71, 645, 621, 101,
+ 346, -112, -125, 348, 257, 99, 71, 645, 621, 101,
-128, 440, 141, 621, 164, 431, 539, 430, 453, 573,
457, 444, 440, 424, 71, 424, 101, 446, 559, 420,
424, 448, 539, 440, 570, 539, 466, 527, 312, 346,
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index 3a0e897..975ad4c 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -484,6 +484,8 @@ int Lexer::lex()
stackToken = -1;
}
+ bool identifierWithEscapedUnicode = false;
+
while (!done) {
switch (state) {
case Start:
@@ -523,7 +525,26 @@ int Lexer::lex()
state = InString;
multiLineString = false;
stringType = current;
+ } else if (current == '\\' && next1 == 'u') {
+ identifierWithEscapedUnicode = true;
+ recordStartPos();
+
+ shift(2); // skip the unicode escape prefix `\u'
+
+ if (isHexDigit(current) && isHexDigit(next1) &&
+ isHexDigit(next2) && isHexDigit(next3)) {
+ record16(convertUnicode(current, next1, next2, next3));
+ shift(3);
+ state = InIdentifier;
+ } else {
+ setDone(Bad);
+ err = IllegalUnicodeEscapeSequence;
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ break;
+ }
+
} else if (isIdentLetter(current)) {
+ identifierWithEscapedUnicode = false;
recordStartPos();
record16(current);
state = InIdentifier;
@@ -683,6 +704,21 @@ int Lexer::lex()
if (isIdentLetter(current) || isDecimalDigit(current)) {
record16(current);
break;
+ } else if (current == '\\' && next1 == 'u') {
+ identifierWithEscapedUnicode = true;
+ shift(2); // skip the unicode escape prefix `\u'
+
+ if (isHexDigit(current) && isHexDigit(next1) &&
+ isHexDigit(next2) && isHexDigit(next3)) {
+ record16(convertUnicode(current, next1, next2, next3));
+ shift(3);
+ break;
+ } else {
+ setDone(Bad);
+ err = IllegalUnicodeEscapeSequence;
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ break;
+ }
}
setDone(Identifier);
break;
@@ -825,7 +861,11 @@ int Lexer::lex()
delimited = true;
return token;
case Identifier:
- if ((token = findReservedWord(buffer16, pos16)) < 0) {
+ token = -1;
+ if (! identifierWithEscapedUnicode)
+ token = findReservedWord(buffer16, pos16);
+
+ if (token < 0) {
/* TODO: close leak on parse error. same holds true for String */
if (driver)
qsyylval.ustr = driver->intern(buffer16, pos16);
@@ -1104,47 +1144,97 @@ void Lexer::recordStartPos()
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
{
pos16 = 0;
- bool lastWasEscape = false;
+ pattern = 0;
if (prefix == EqualPrefix)
record16(QLatin1Char('='));
- while (1) {
- if (isLineTerminator() || current == 0) {
+ while (true) {
+ switch (current) {
+
+ case 0: // eof
+ case '\n': case '\r': // line terminator
errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression literal");
return false;
- }
- else if (current != '/' || lastWasEscape == true)
- {
- record16(current);
- lastWasEscape = !lastWasEscape && (current == '\\');
- }
- else {
- if (driver)
+
+ case '/':
+ shift(1);
+
+ if (driver) // create the pattern
pattern = driver->intern(buffer16, pos16);
- else
- pattern = 0;
+
+ // scan the flags
pos16 = 0;
+ flags = 0;
+ while (isIdentLetter(current)) {
+ int flag = Ecma::RegExp::flagFromChar(current);
+ if (flag == 0) {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
+ .arg(QChar(current));
+ return false;
+ }
+ flags |= flag;
+ record16(current);
+ shift(1);
+ }
+ return true;
+
+ case '\\':
+ // regular expression backslash sequence
+ record16(current);
+ shift(1);
+
+ if (! current || isLineTerminator()) {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+ return false;
+ }
+
+ record16(current);
shift(1);
break;
- }
- shift(1);
- }
- flags = 0;
- while (isIdentLetter(current)) {
- int flag = Ecma::RegExp::flagFromChar(current);
- if (flag == 0) {
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
- .arg(QChar(current));
- return false;
- }
- flags |= flag;
- record16(current);
- shift(1);
- }
+ case '[':
+ // regular expression class
+ record16(current);
+ shift(1);
+
+ while (current && ! isLineTerminator()) {
+ if (current == ']')
+ break;
+ else if (current == '\\') {
+ // regular expression backslash sequence
+ record16(current);
+ shift(1);
+
+ if (! current || isLineTerminator()) {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+ return false;
+ }
+
+ record16(current);
+ shift(1);
+ } else {
+ record16(current);
+ shift(1);
+ }
+ }
+
+ if (current != ']') {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression class");
+ return false;
+ }
+
+ record16(current);
+ shift(1); // skip ]
+ break;
+
+ default:
+ record16(current);
+ shift(1);
+ } // switch
+ } // while
- return true;
+ return false;
}
void Lexer::syncProhibitAutomaticSemicolon()
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 6e36d4f..d75f0a8 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -100,6 +100,7 @@ int qmlRegisterType()
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
0, 0,
+ QString(),
0, 0, 0, 0, &T::staticMetaObject,
@@ -118,8 +119,10 @@ int qmlRegisterType()
return QDeclarativePrivate::registerType(type);
}
+int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message);
+
template<typename T>
-int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
{
QByteArray name(T::staticMetaObject.className());
@@ -132,6 +135,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
0, 0,
+ reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -164,6 +168,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
sizeof(T), QDeclarativePrivate::createInto<T>,
+ QString(),
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -196,6 +201,7 @@ int qmlRegisterExtendedType()
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
0, 0,
+ QString(),
0, 0, 0, 0, &T::staticMetaObject,
@@ -236,6 +242,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
sizeof(T), QDeclarativePrivate::createInto<T>,
+ QString(),
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -276,9 +283,9 @@ int qmlRegisterInterface(const char *typeName)
template<typename T>
int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
- const char *qmlName, const char *typeName, QDeclarativeCustomParser *parser)
+ const char *qmlName, QDeclarativeCustomParser *parser)
{
- QByteArray name(typeName);
+ QByteArray name(T::staticMetaObject.className());
QByteArray pointerName(name + '*');
QByteArray listName("QDeclarativeListProperty<" + name + ">");
@@ -289,6 +296,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
sizeof(T), QDeclarativePrivate::createInto<T>,
+ QString(),
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 25492ac..d44e7fb 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -156,6 +156,9 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
QScriptValue scriptValue = d->scriptValue(0, &isUndefined);
if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) {
value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >());
+ } else if (scriptValue.isNull() &&
+ data->property.propertyTypeCategory() == QDeclarativeProperty::Object) {
+ value = QVariant::fromValue((QObject *)0);
} else {
value = ep->scriptValueToVariant(scriptValue, data->property.propertyType());
if (value.userType() == QMetaType::QObjectStar && !qvariant_cast<QObject*>(value)) {
@@ -168,6 +171,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
}
}
+
if (data->error.isValid()) {
} else if (isUndefined && data->property.isResettable()) {
@@ -210,8 +214,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
}
if (data->error.isValid()) {
- if (!data->addError(ep))
- qWarning().nospace() << qPrintable(this->error().toString());
+ if (!data->addError(ep)) ep->warning(this->error());
} else {
data->removeError();
}
@@ -358,8 +361,10 @@ void QDeclarativeAbstractBinding::removeFromObject()
void QDeclarativeAbstractBinding::clear()
{
- if (m_mePtr)
+ if (m_mePtr) {
*m_mePtr = 0;
+ m_mePtr = 0;
+ }
}
QString QDeclarativeAbstractBinding::expression() const
diff --git a/src/declarative/qml/qdeclarativeboundsignal.cpp b/src/declarative/qml/qdeclarativeboundsignal.cpp
index 8c7a977..89f1256 100644
--- a/src/declarative/qml/qdeclarativeboundsignal.cpp
+++ b/src/declarative/qml/qdeclarativeboundsignal.cpp
@@ -95,10 +95,8 @@ QDeclarativeAbstractBoundSignal::~QDeclarativeAbstractBoundSignal()
QDeclarativeBoundSignal::QDeclarativeBoundSignal(QObject *scope, const QMetaMethod &signal,
QObject *parent)
-: m_expression(0), m_signal(signal), m_paramsValid(false), m_params(0)
+: m_expression(0), m_signal(signal), m_paramsValid(false), m_isEvaluating(false), m_params(0)
{
- // A cached evaluation of the QDeclarativeExpression::value() slot index.
- //
// This is thread safe. Although it may be updated by two threads, they
// will both set it to the same value - so the worst thing that can happen
// is that they both do the work to figure it out. Boo hoo.
@@ -111,10 +109,8 @@ QDeclarativeBoundSignal::QDeclarativeBoundSignal(QObject *scope, const QMetaMeth
QDeclarativeBoundSignal::QDeclarativeBoundSignal(QDeclarativeContext *ctxt, const QString &val,
QObject *scope, const QMetaMethod &signal,
QObject *parent)
-: m_expression(0), m_signal(signal), m_paramsValid(false), m_params(0)
+: m_expression(0), m_signal(signal), m_paramsValid(false), m_isEvaluating(false), m_params(0)
{
- // A cached evaluation of the QDeclarativeExpression::value() slot index.
- //
// This is thread safe. Although it may be updated by two threads, they
// will both set it to the same value - so the worst thing that can happen
// is that they both do the work to figure it out. Boo hoo.
@@ -169,6 +165,7 @@ QDeclarativeBoundSignal *QDeclarativeBoundSignal::cast(QObject *o)
int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
{
if (c == QMetaObject::InvokeMetaMethod && id == evaluateIdx) {
+ m_isEvaluating = true;
if (!m_paramsValid) {
if (!m_signal.parameterTypes().isEmpty())
m_params = new QDeclarativeBoundSignalParameters(m_signal, this);
@@ -179,9 +176,10 @@ int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
if (m_expression && m_expression->engine()) {
QDeclarativeExpressionPrivate::get(m_expression)->value(m_params);
if (m_expression && m_expression->hasError())
- qWarning().nospace() << qPrintable(m_expression->error().toString());
+ QDeclarativeEnginePrivate::warning(m_expression->engine(), m_expression->error());
}
if (m_params) m_params->clearValues();
+ m_isEvaluating = false;
return -1;
} else {
return QObject::qt_metacall(c, id, a);
diff --git a/src/declarative/qml/qdeclarativeboundsignal_p.h b/src/declarative/qml/qdeclarativeboundsignal_p.h
index bba4eec..06900d7 100644
--- a/src/declarative/qml/qdeclarativeboundsignal_p.h
+++ b/src/declarative/qml/qdeclarativeboundsignal_p.h
@@ -83,6 +83,8 @@ public:
QDeclarativeExpression *expression() const;
QDeclarativeExpression *setExpression(QDeclarativeExpression *);
+ bool isEvaluating() const { return m_isEvaluating; }
+
static QDeclarativeBoundSignal *cast(QObject *);
protected:
@@ -91,7 +93,8 @@ protected:
private:
QDeclarativeExpression *m_expression;
QMetaMethod m_signal;
- bool m_paramsValid;
+ bool m_paramsValid : 1;
+ bool m_isEvaluating : 1;
QDeclarativeBoundSignalParameters *m_params;
};
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 6fdf706..6596aba 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -888,13 +888,6 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output,
return;
}
- for (int ii = 0; ii < context->scripts.count(); ++ii) {
- QScriptValue function = QScriptDeclarativeClass::function(context->scripts.at(ii), name);
- if (function.isValid()) {
- qFatal("Binding optimizer resolved name to QScript method");
- }
- }
-
if (QObject *root = context->contextObject) {
if (findproperty(root, output, enginePriv, subIdx, name, isTerminal))
@@ -938,7 +931,7 @@ static void throwException(int id, QDeclarativeDelayedError *error,
error->error.setColumn(-1);
}
if (!context->engine || !error->addError(QDeclarativeEnginePrivate::get(context->engine)))
- qWarning() << error->error;
+ QDeclarativeEnginePrivate::warning(context->engine, error->error);
}
static void dumpInstruction(const Instr *instr)
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 065009a..1727687 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -571,8 +571,12 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
QDeclarativeScriptParser::TypeReference *parserRef = unit->data.referencedTypes().at(ii);
if (tref.type) {
ref.type = tref.type;
- if (!ref.type->isCreatable())
- COMPILE_EXCEPTION(parserRef->refObjects.first(), tr( "Element is not creatable."));
+ if (!ref.type->isCreatable()) {
+ QString err = ref.type->noCreationReason();
+ if (err.isEmpty())
+ err = tr( "Element is not creatable.");
+ COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
+ }
} else if (tref.unit) {
ref.component = tref.unit->toComponent(engine);
@@ -733,10 +737,6 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt)
return true;
}
- // Build any script blocks for this type
- for (int ii = 0; ii < obj->scriptBlockObjects.count(); ++ii)
- COMPILE_CHECK(buildScript(obj, obj->scriptBlockObjects.at(ii)));
-
// Object instantiations reset the binding context
BindingContext objCtxt(obj);
@@ -868,12 +868,14 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt)
defaultProperty->release();
// Compile custom parser parts
- if (isCustomParser && !customProps.isEmpty()) {
+ if (isCustomParser/* && !customProps.isEmpty()*/) {
QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser();
cp->clearErrors();
cp->compiler = this;
+ cp->object = obj;
obj->custom = cp->compile(customProps);
cp->compiler = 0;
+ cp->object = 0;
foreach (QDeclarativeError err, cp->errors()) {
err.setUrl(output->url);
exceptions << err;
@@ -961,17 +963,6 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
output->bytecode << id;
}
- // Set any script blocks
- for (int ii = 0; ii < obj->scripts.count(); ++ii) {
- QDeclarativeInstruction script;
- script.type = QDeclarativeInstruction::StoreScript;
- script.line = 0; // ###
- int idx = output->scripts.count();
- output->scripts << obj->scripts.at(ii);
- script.storeScript.value = idx;
- output->bytecode << script;
- }
-
// Begin the class
if (obj->parserStatusCast != -1) {
QDeclarativeInstruction begin;
@@ -1177,9 +1168,6 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
(obj->properties.count() == 1 && obj->properties.begin().key() != "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(), tr("Component elements may not contain script blocks"));
-
if (obj->properties.count())
idProp = *obj->properties.begin();
@@ -1203,6 +1191,13 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
(obj->defaultProperty->values.count() == 1 && !obj->defaultProperty->values.first()->object)))
COMPILE_EXCEPTION(obj, tr("Invalid component body specification"));
+ if (!obj->dynamicProperties.isEmpty())
+ COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new properties."));
+ if (!obj->dynamicSignals.isEmpty())
+ COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new signals."));
+ if (!obj->dynamicSlots.isEmpty())
+ COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new functions."));
+
Object *root = 0;
if (obj->defaultProperty && obj->defaultProperty->values.count())
root = obj->defaultProperty->values.first()->object;
@@ -1216,94 +1211,6 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
return true;
}
-bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclarativeParser::Object *script)
-{
- qWarning().nospace() << qPrintable(output->url.toString()) << ":" << obj->location.start.line << ":" << obj->location.start.column << ": Script blocks have been deprecated. Support will be removed entirely shortly.";
-
- Object::ScriptBlock scriptBlock;
-
- if (script->properties.count() == 1 &&
- script->properties.begin().key() == QByteArray("source")) {
-
- Property *source = *script->properties.begin();
- if (script->defaultProperty)
- 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, tr("Invalid Script source value"));
-
- QStringList sources = source->values.at(0)->value.asStringList();
-
- for (int jj = 0; jj < sources.count(); ++jj) {
- QString sourceUrl = output->url.resolved(QUrl(sources.at(jj))).toString();
- QString scriptCode;
- int lineNumber = 1;
-
- for (int ii = 0; ii < unit->resources.count(); ++ii) {
- if (unit->resources.at(ii)->url == sourceUrl) {
- scriptCode = QString::fromUtf8(unit->resources.at(ii)->data);
- break;
- }
- }
-
- if (!scriptCode.isEmpty()) {
- scriptBlock.codes.append(scriptCode);
- scriptBlock.files.append(sourceUrl);
- scriptBlock.lineNumbers.append(lineNumber);
- scriptBlock.pragmas.append(Object::ScriptBlock::None);
- }
- }
-
- } else if (!script->properties.isEmpty()) {
- COMPILE_EXCEPTION(*script->properties.begin(), tr("Properties cannot be set on Script block"));
- } else if (script->defaultProperty) {
-
- QString scriptCode;
- int lineNumber = 1;
- QString sourceUrl = output->url.toString();
-
- QDeclarativeParser::Location currentLocation;
-
- for (int ii = 0; ii < script->defaultProperty->values.count(); ++ii) {
- Value *v = script->defaultProperty->values.at(ii);
- if (lineNumber == 1)
- lineNumber = v->location.start.line;
- if (v->object || !v->value.isString())
- COMPILE_EXCEPTION(v, tr("Invalid Script block"));
-
- if (ii == 0) {
- currentLocation = v->location.start;
- scriptCode.append(QString(currentLocation.column, QLatin1Char(' ')));
- }
-
- while (currentLocation.line < v->location.start.line) {
- scriptCode.append(QLatin1Char('\n'));
- currentLocation.line++;
- currentLocation.column = 0;
- }
-
- scriptCode.append(QString(v->location.start.column - currentLocation.column, QLatin1Char(' ')));
-
- scriptCode += v->value.asString();
- currentLocation = v->location.end;
- currentLocation.column++;
- }
-
- if (!scriptCode.isEmpty()) {
- scriptBlock.codes.append(scriptCode);
- scriptBlock.files.append(sourceUrl);
- scriptBlock.lineNumbers.append(lineNumber);
- scriptBlock.pragmas.append(Object::ScriptBlock::None);
- }
- }
-
- if (!scriptBlock.codes.isEmpty())
- obj->scripts << scriptBlock;
-
- return true;
-}
-
bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *obj,
const BindingContext &ctxt)
{
@@ -1351,7 +1258,7 @@ bool QDeclarativeCompiler::buildSubObject(Object *obj, const BindingContext &ctx
int QDeclarativeCompiler::componentTypeRef()
{
- QDeclarativeType *t = QDeclarativeMetaType::qmlType("Qt/Component",4,6);
+ QDeclarativeType *t = QDeclarativeMetaType::qmlType("Qt/Component",4,7);
for (int ii = output->types.count() - 1; ii >= 0; --ii) {
if (output->types.at(ii).type == t)
return ii;
@@ -2902,25 +2809,6 @@ bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeParser::Object *from)
return false;
}
-/*!
- Returns true if from can be assigned to a (QObject) property of type
- to.
-*/
-bool QDeclarativeCompiler::canCoerce(int to, int from)
-{
- const QMetaObject *toMo =
- QDeclarativeEnginePrivate::get(engine)->rawMetaObjectForType(to);
- const QMetaObject *fromMo =
- QDeclarativeEnginePrivate::get(engine)->rawMetaObjectForType(from);
-
- while (fromMo) {
- if (QDeclarativePropertyPrivate::equal(fromMo, toMo))
- return true;
- fromMo = fromMo->superClass();
- }
- return false;
-}
-
QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeParser::Object *from)
{
// ### Optimize
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 867db2c..fefab7a 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -186,7 +186,6 @@ private:
bool buildObject(QDeclarativeParser::Object *obj, const BindingContext &);
- bool buildScript(QDeclarativeParser::Object *obj, QDeclarativeParser::Object *script);
bool buildComponent(QDeclarativeParser::Object *obj, const BindingContext &);
bool buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &);
bool buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
@@ -275,7 +274,6 @@ private:
static QDeclarativeType *toQmlType(QDeclarativeParser::Object *from);
bool canCoerce(int to, QDeclarativeParser::Object *from);
- bool canCoerce(int to, int from);
QStringList deferredProperties(QDeclarativeParser::Object *);
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 3e4651c..3899e73 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -67,14 +67,14 @@ int statusId = qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeCom
/*!
\class QDeclarativeComponent
- \since 4.7
+ \since 4.7
\brief The QDeclarativeComponent class encapsulates a QML component description.
\mainclass
*/
/*!
\qmlclass Component QDeclarativeComponent
- \since 4.7
+ \since 4.7
\brief The Component element encapsulates a QML component description.
Components are reusable, encapsulated Qml element with a well-defined interface.
@@ -86,26 +86,26 @@ int statusId = qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeCom
file containing it.
\qml
-Item {
- Component {
- id: redSquare
- Rectangle {
- color: "red"
- width: 10
- height: 10
+ Item {
+ Component {
+ id: redSquare
+ Rectangle {
+ color: "red"
+ width: 10
+ height: 10
+ }
}
+ Loader { sourceComponent: redSquare }
+ Loader { sourceComponent: redSquare; x: 20 }
}
- Loader { sourceComponent: redSquare }
- Loader { sourceComponent: redSquare; x: 20 }
-}
\endqml
+*/
- \section1 Attached Properties
-
- \e onCompleted
+/*!
+ \qmlattachedsignal Component::onCompleted()
Emitted after component "startup" has completed. This can be used to
- execute script code at startup, once the full QML environment has been
+ execute script code at startup, once the full QML environment has been
established.
The \c {Component::onCompleted} attached property can be applied to
@@ -120,8 +120,10 @@ Item {
}
}
\endqml
+*/
- \e onDestruction
+/*!
+ \qmlattachedsignal Component::onDestruction()
Emitted as the component begins destruction. This can be used to undo
work done in the onCompleted signal, or other imperative code in your
@@ -129,7 +131,7 @@ Item {
The \c {Component::onDestruction} attached property can be applied to
any element. However, it applies to the destruction of the component as
- a whole, and not the destruction of the specific object. The order of
+ a whole, and not the destruction of the specific object. The order of
running the \c onDestruction scripts is undefined.
\qml
@@ -530,10 +532,8 @@ QScriptValue QDeclarativeComponent::createObject()
{
Q_D(QDeclarativeComponent);
QDeclarativeContext* ctxt = creationContext();
- if(!ctxt){
- qWarning() << QLatin1String("createObject can only be used in QML");
+ if(!ctxt)
return QScriptValue();
- }
QObject* ret = create(ctxt);
if (!ret)
return QScriptValue();
@@ -613,17 +613,17 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons
{
Q_Q(QDeclarativeComponent);
if (!context) {
- qWarning("QDeclarativeComponent::beginCreate(): Cannot create a component in a null context");
+ qWarning("QDeclarativeComponent: Cannot create a component in a null context");
return 0;
}
if (!context->isValid()) {
- qWarning("QDeclarativeComponent::beginCreate(): Cannot create a component in an invalid context");
+ qWarning("QDeclarativeComponent: Cannot create a component in an invalid context");
return 0;
}
if (context->engine != engine) {
- qWarning("QDeclarativeComponent::beginCreate(): Must create component in context from the same QDeclarativeEngine");
+ qWarning("QDeclarativeComponent: Must create component in context from the same QDeclarativeEngine");
return 0;
}
@@ -766,7 +766,7 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
enginePriv->inProgressCreations--;
if (0 == enginePriv->inProgressCreations) {
while (enginePriv->erroredBindings) {
- qWarning().nospace() << qPrintable(enginePriv->erroredBindings->error.toString());
+ enginePriv->warning(enginePriv->erroredBindings->error);
enginePriv->erroredBindings->removeError();
}
}
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index 6ee5070..f3cfe3c 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -99,8 +99,6 @@ public:
virtual QObject *beginCreate(QDeclarativeContext *);
virtual void completeCreate();
- Q_INVOKABLE QScriptValue createObject();
-
void loadUrl(const QUrl &url);
void setData(const QByteArray &, const QUrl &baseUrl);
@@ -114,10 +112,12 @@ Q_SIGNALS:
protected:
QDeclarativeComponent(QDeclarativeComponentPrivate &dd, QObject* parent);
+ Q_INVOKABLE QScriptValue createObject();
private:
QDeclarativeComponent(QDeclarativeEngine *, QDeclarativeCompiledData *, int, int, QObject *parent);
+ Q_DISABLE_COPY(QDeclarativeComponent)
friend class QDeclarativeVME;
friend class QDeclarativeCompositeTypeData;
};
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
index 133b71f..adeb7a5 100644
--- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp
+++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
@@ -341,7 +341,6 @@ static QString toLocalFileOrQrc(const QUrl& url)
if (url.scheme() == QLatin1String("qrc")) {
if (url.authority().isEmpty())
return QLatin1Char(':') + url.path();
- qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known.";
return QString();
}
return url.toLocalFile();
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 6657fea..ae4223e 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -114,7 +114,7 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
\endcode
All properties added explicitly by QDeclarativeContext::setContextProperty() take
- precedence over context object's properties.
+ precedence over the context object's properties.
Contexts form a hierarchy. The root of this heirarchy is the QDeclarativeEngine's
\l {QDeclarativeEngine::rootContext()}{root context}. A component instance can
@@ -140,6 +140,11 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
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.
+
+ \note Setting the context object or adding new context properties after an object
+ has been created in that context is an expensive operation (essentially forcing all bindings
+ to reevaluate). Thus whenever possible you should complete "setup" of the context
+ before using it to create any objects.
*/
/*! \internal */
@@ -203,6 +208,12 @@ QDeclarativeContext::~QDeclarativeContext()
d->data->destroy();
}
+/*!
+ Returns whether the context is valid.
+
+ To be valid, a context must have a engine, and it's contextObject(), if any,
+ must not have been deleted.
+*/
bool QDeclarativeContext::isValid() const
{
Q_D(const QDeclarativeContext);
@@ -655,7 +666,7 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object
if (scriptEngine->hasUncaughtException()) {
QDeclarativeError error;
QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
- qWarning().nospace() << qPrintable(error.toString());
+ enginePriv->warning(error);
}
scriptEngine->popContext();
@@ -681,7 +692,7 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object
if (scriptEngine->hasUncaughtException()) {
QDeclarativeError error;
QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
- qWarning().nospace() << qPrintable(error.toString());
+ enginePriv->warning(error);
}
scriptEngine->popContext();
@@ -691,39 +702,6 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object
}
}
-void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script,
- QObject *scopeObject)
-{
- if (!engine)
- return;
-
- QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
- QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
-
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
-
- scriptContext->pushScope(enginePriv->contextClass->newContext(this, scopeObject));
- scriptContext->pushScope(enginePriv->globalClass->globalObject());
-
- QScriptValue scope = scriptEngine->newObject();
- scriptContext->setActivationObject(scope);
- scriptContext->pushScope(scope);
-
- for (int ii = 0; ii < script.codes.count(); ++ii) {
- scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii));
-
- if (scriptEngine->hasUncaughtException()) {
- QDeclarativeError error;
- QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
- qWarning().nospace() << qPrintable(error.toString());
- }
- }
-
- scriptEngine->popContext();
-
- scripts.append(scope);
-}
-
void QDeclarativeContextData::setIdProperty(int idx, QObject *obj)
{
idValues[idx] = obj;
diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h
index 94c9f4a..548869c 100644
--- a/src/declarative/qml/qdeclarativecontext.h
+++ b/src/declarative/qml/qdeclarativecontext.h
@@ -103,6 +103,7 @@ private:
friend class QDeclarativeContextData;
QDeclarativeContext(QDeclarativeContextData *);
QDeclarativeContext(QDeclarativeEngine *, bool);
+ Q_DISABLE_COPY(QDeclarativeContext)
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 77a6d94..c7fb099 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -145,10 +145,8 @@ public:
QObject *contextObject;
// Any script blocks that exist on this context
- QList<QScriptValue> scripts;
QList<QScriptValue> importedScripts;
void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script);
- void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject);
// Context base url
QUrl url;
diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
index 461fab5..1336a1a 100644
--- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
@@ -189,14 +189,6 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindConte
}
}
- for (int ii = 0; ii < bindContext->scripts.count(); ++ii) {
- lastFunction = QScriptDeclarativeClass::function(bindContext->scripts.at(ii), name);
- if (lastFunction.isValid()) {
- lastContext = bindContext;
- return QScriptClass::HandlesReadAccess;
- }
- }
-
if (scopeObject) {
QScriptClass::QueryFlags rv =
ep->objectClass->queryProperty(scopeObject, name, flags, bindContext,
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index 1a97315..472a883 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -89,6 +89,8 @@ using namespace QDeclarativeParser;
by \a data, which is a block of data previously returned by a call
to compile().
+ Errors should be reported using qmlInfo(object).
+
The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
*/
@@ -235,6 +237,24 @@ void QDeclarativeCustomParser::clearErrors()
}
/*!
+ Reports an error with the given \a description.
+
+ This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().
+
+ An error is generated referring to the position of the element in the source file.
+*/
+void QDeclarativeCustomParser::error(const QString& description)
+{
+ Q_ASSERT(object);
+ QDeclarativeError error;
+ QString exceptionDescription;
+ error.setLine(object->location.start.line);
+ error.setColumn(object->location.start.column);
+ error.setDescription(description);
+ exceptions << error;
+}
+
+/*!
Reports an error in parsing \a prop, with the given \a description.
An error is generated referring to the position of \a node in the source file.
diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h
index da0358a..0e397c5 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p.h
@@ -113,7 +113,7 @@ private:
class Q_DECLARATIVE_EXPORT QDeclarativeCustomParser
{
public:
- QDeclarativeCustomParser() : compiler(0) {}
+ QDeclarativeCustomParser() : compiler(0), object(0) {}
virtual ~QDeclarativeCustomParser() {}
void clearErrors();
@@ -124,6 +124,7 @@ public:
QList<QDeclarativeError> errors() const { return exceptions; }
protected:
+ void error(const QString& description);
void error(const QDeclarativeCustomParserProperty&, const QString& description);
void error(const QDeclarativeCustomParserNode&, const QString& description);
@@ -132,6 +133,7 @@ protected:
private:
QList<QDeclarativeError> exceptions;
QDeclarativeCompiler *compiler;
+ QDeclarativeParser::Object *object;
friend class QDeclarativeCompiler;
};
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h
index 2ddd7e5..4a56536 100644
--- a/src/declarative/qml/qdeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedata_p.h
@@ -75,7 +75,7 @@ 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), scriptValue(0), propertyCache(0), guards(0) {
+ attachedProperties(0), scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0) {
init();
}
@@ -128,6 +128,7 @@ public:
// ### Can we make this QScriptValuePrivate so we incur no additional allocation
// cost?
QScriptValue *scriptValue;
+ quint32 objectDataRefCount;
QDeclarativePropertyCache *propertyCache;
QDeclarativeGuard<QObject> *guards;
diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp
index 1e3b37b..3e05853 100644
--- a/src/declarative/qml/qdeclarativedirparser.cpp
+++ b/src/declarative/qml/qdeclarativedirparser.cpp
@@ -170,10 +170,9 @@ bool QDeclarativeDirParser::parse()
const int dotIndex = version.indexOf(QLatin1Char('.'));
if (dotIndex == -1) {
- qWarning() << "expected '.'"; // ### use reportError
+ reportError(lineNumber, -1, QLatin1String("expected '.'"));
} else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) {
- qWarning() << "unexpected '.'"; // ### use reportError
-
+ reportError(lineNumber, -1, QLatin1String("unexpected '.'"));
} else {
bool validVersionNumber = false;
const int majorVersion = version.left(dotIndex).toInt(&validVersionNumber);
@@ -189,8 +188,8 @@ bool QDeclarativeDirParser::parse()
}
}
} else {
- // ### use reportError
- qWarning() << "a component declaration requires 3 arguments, but" << (sectionCount + 1) << "were provided";
+ reportError(lineNumber, -1,
+ QString::fromUtf8("a component declaration requires 3 arguments, but %1 were provided").arg(sectionCount + 1));
}
}
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 96145fb..8eae120 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -144,19 +144,19 @@ static bool qt_QmlQtModule_registered = false;
void QDeclarativeEnginePrivate::defineModule()
{
- qmlRegisterType<QDeclarativeComponent>("Qt",4,6,"Component");
- qmlRegisterType<QObject>("Qt",4,6,"QtObject");
- qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,6,"WorkerScript");
+ qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
+ qmlRegisterType<QObject>("Qt",4,7,"QtObject");
+ qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
qmlRegisterType<QDeclarativeBinding>();
}
QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
-: captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false),
- contextClass(0), sharedContext(0), sharedScope(0), objectClass(0), valueTypeClass(0),
- globalClass(0), cleanup(0), erroredBindings(0), inProgressCreations(0),
- scriptEngine(this), workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
- networkAccessManager(0), networkAccessManagerFactory(0),
+: captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false),
+ outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0),
+ objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
+ inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
+ inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
typeManager(e), uniqueId(1)
{
if (!qt_QmlQtModule_registered) {
@@ -216,8 +216,6 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr
offlineStoragePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace(QLatin1Char('/'), QDir::separator())
+ QDir::separator() + QLatin1String("QML")
+ QDir::separator() + QLatin1String("OfflineStorage");
-#else
- qWarning("offlineStoragePath is not set by default with QT_NO_DESKTOPSERVICES");
#endif
qt_add_qmlxmlhttprequest(this);
@@ -256,19 +254,19 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr
qtObject.setProperty(QLatin1String("quit"), newFunction(QDeclarativeEnginePrivate::quit, 0));
qtObject.setProperty(QLatin1String("resolvedUrl"),newFunction(QDeclarativeScriptEngine::resolvedUrl, 1));
+ if (mainthread) {
+ qtObject.setProperty(QLatin1String("createQmlObject"),
+ newFunction(QDeclarativeEnginePrivate::createQmlObject, 1));
+ qtObject.setProperty(QLatin1String("createComponent"),
+ newFunction(QDeclarativeEnginePrivate::createComponent, 1));
+ }
+
//firebug/webkit compat
QScriptValue consoleObject = newObject();
consoleObject.setProperty(QLatin1String("log"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
consoleObject.setProperty(QLatin1String("debug"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
globalObject().setProperty(QLatin1String("console"), consoleObject);
- if (mainthread) {
- globalObject().setProperty(QLatin1String("createQmlObject"),
- newFunction(QDeclarativeEnginePrivate::createQmlObject, 1));
- globalObject().setProperty(QLatin1String("createComponent"),
- newFunction(QDeclarativeEnginePrivate::createComponent, 1));
- }
-
// translation functions need to be installed
// before the global script class is constructed (QTBUG-6437)
installTranslatorFunctions();
@@ -355,7 +353,7 @@ void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
QObjectPrivate *p = QObjectPrivate::get(o);
Q_ASSERT(p->declarativeData);
QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
- if (d->ownContext)
+ if (d->ownContext)
d->context->destroy();
}
@@ -390,15 +388,13 @@ void QDeclarativeEnginePrivate::init()
qmlEngineDebugServer();
isDebugging = true;
QDeclarativeEngineDebugServer::addEngine(q);
-
- qmlEngineDebugServer()->waitForClients();
}
}
QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
{
Q_Q(QDeclarativeEngine);
- if (!workerScriptEngine)
+ if (!workerScriptEngine)
workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
return workerScriptEngine;
}
@@ -423,7 +419,7 @@ QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine
QDeclarativeComponent component(&engine);
component.setData("import Qt 4.7\nText { text: \"Hello world!\" }", QUrl());
QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
-
+
//add item to view, etc
...
\endcode
@@ -655,6 +651,34 @@ void QDeclarativeEngine::setBaseUrl(const QUrl &url)
}
/*!
+ Returns true if warning messages will be output to stderr in addition
+ to being emitted by the warnings() signal, otherwise false.
+
+ The default value is true.
+*/
+bool QDeclarativeEngine::outputWarningsToStandardError() const
+{
+ Q_D(const QDeclarativeEngine);
+ return d->outputWarningsToStdErr;
+}
+
+/*!
+ Set whether warning messages will be output to stderr to \a enabled.
+
+ If \a enabled is true, any warning messages generated by QML will be
+ output to stderr and emitted by the warnings() signal. If \a enabled
+ is false, on the warnings() signal will be emitted. This allows
+ applications to handle warning output themselves.
+
+ The default value is true.
+*/
+void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
+{
+ Q_D(QDeclarativeEngine);
+ d->outputWarningsToStdErr = enabled;
+}
+
+/*!
Returns the QDeclarativeContext for the \a object, or 0 if no
context has been set.
@@ -743,6 +767,9 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex
*/
void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
{
+ if (!object)
+ return;
+
QDeclarativeData *ddata = QDeclarativeData::get(object, true);
if (!ddata)
return;
@@ -756,8 +783,11 @@ void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership own
*/
QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
{
+ if (!object)
+ return CppOwnership;
+
QDeclarativeData *ddata = QDeclarativeData::get(object, false);
- if (!ddata)
+ if (!ddata)
return CppOwnership;
else
return ddata->indestructible?CppOwnership:JavaScriptOwnership;
@@ -780,8 +810,7 @@ void qmlExecuteDeferred(QObject *object)
QDeclarativeComponentPrivate::complete(ep, &state);
if (!state.errors.isEmpty())
- qWarning() << state.errors;
-
+ ep->warning(state.errors);
}
}
@@ -821,7 +850,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
return rv;
}
-QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
+QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
const QMetaObject *attachedMetaObject, bool create)
{
if (*idCache == -1)
@@ -840,7 +869,7 @@ void QDeclarativeData::destroyed(QObject *object)
if (attachedProperties)
delete attachedProperties;
- if (nextContextObject)
+ if (nextContextObject)
nextContextObject->prevContextObject = prevContextObject;
if (prevContextObject)
*prevContextObject = nextContextObject;
@@ -887,7 +916,7 @@ void QDeclarativeData::parentChanged(QObject *, QObject *parent)
bool QDeclarativeData::hasBindingBit(int bit) const
{
- if (bindingBitsSize > bit)
+ if (bindingBitsSize > bit)
return bindingBits[bit / 32] & (1 << (bit % 32));
else
return false;
@@ -895,7 +924,7 @@ bool QDeclarativeData::hasBindingBit(int bit) const
void QDeclarativeData::clearBindingBit(int bit)
{
- if (bindingBitsSize > bit)
+ if (bindingBitsSize > bit)
bindingBits[bit / 32] &= ~(1 << (bit % 32));
}
@@ -908,10 +937,10 @@ void QDeclarativeData::setBindingBit(QObject *obj, int bit)
int arraySize = (props + 31) / 32;
int oldArraySize = bindingBitsSize / 32;
- bindingBits = (quint32 *)realloc(bindingBits,
+ bindingBits = (quint32 *)realloc(bindingBits,
arraySize * sizeof(quint32));
- memset(bindingBits + oldArraySize,
+ memset(bindingBits + oldArraySize,
0x00,
sizeof(quint32) * (arraySize - oldArraySize));
@@ -957,7 +986,7 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS
Q_ASSERT(context);
if(ctxt->argumentCount() != 1) {
- return engine->nullValue();
+ return ctxt->throwError("Qt.createComponent(): Invalid arguments");
}else{
QString arg = ctxt->argument(0).toString();
if (arg.isEmpty())
@@ -977,7 +1006,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
- return engine->nullValue();
+ return ctxt->throwError("Qt.createQmlObject(): Invalid arguments");
QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
Q_ASSERT(context);
@@ -996,36 +1025,53 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
url = context->resolvedUrl(url);
QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
- if(!parentArg)
- return engine->nullValue();
+ if(!parentArg)
+ return ctxt->throwError("Qt.createQmlObject(): Missing parent object");
QDeclarativeComponent component(activeEngine);
component.setData(qml.toUtf8(), url);
if(component.isError()) {
QList<QDeclarativeError> errors = component.errors();
- qWarning().nospace() << "QDeclarativeEngine::createQmlObject():";
- foreach (const QDeclarativeError &error, errors)
- qWarning().nospace() << " " << error;
-
- return engine->nullValue();
+ QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
+ QScriptValue arr = ctxt->engine()->newArray(errors.length());
+ int i = 0;
+ foreach (const QDeclarativeError &error, errors){
+ errstr += QLatin1String(" ") + error.toString() + QLatin1String("\n");
+ QScriptValue qmlErrObject = ctxt->engine()->newObject();
+ qmlErrObject.setProperty("lineNumber", QScriptValue(error.line()));
+ qmlErrObject.setProperty("columnNumber", QScriptValue(error.column()));
+ qmlErrObject.setProperty("fileName", QScriptValue(error.url().toString()));
+ qmlErrObject.setProperty("message", QScriptValue(error.description()));
+ arr.setProperty(i++, qmlErrObject);
+ }
+ QScriptValue err = ctxt->throwError(errstr);
+ err.setProperty("qmlErrors",arr);
+ return err;
}
- if (!component.isReady()) {
- qWarning().nospace() << "QDeclarativeEngine::createQmlObject(): Component is not ready";
-
- return engine->nullValue();
- }
+ if (!component.isReady())
+ return ctxt->throwError("Qt.createQmlObject(): Component is not ready");
QObject *obj = component.create(context->asQDeclarativeContext());
if(component.isError()) {
QList<QDeclarativeError> errors = component.errors();
- qWarning().nospace() << "QDeclarativeEngine::createQmlObject():";
- foreach (const QDeclarativeError &error, errors)
- qWarning().nospace() << " " << error;
-
- return engine->nullValue();
+ QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
+ QScriptValue arr = ctxt->engine()->newArray(errors.length());
+ int i = 0;
+ foreach (const QDeclarativeError &error, errors){
+ errstr += QLatin1String(" ") + error.toString() + QLatin1String("\n");
+ QScriptValue qmlErrObject = ctxt->engine()->newObject();
+ qmlErrObject.setProperty("lineNumber", QScriptValue(error.line()));
+ qmlErrObject.setProperty("columnNumber", QScriptValue(error.column()));
+ qmlErrObject.setProperty("fileName", QScriptValue(error.url().toString()));
+ qmlErrObject.setProperty("message", QScriptValue(error.description()));
+ arr.setProperty(i++, qmlErrObject);
+ }
+ QScriptValue err = ctxt->throwError(errstr);
+ err.setProperty("qmlErrors",arr);
+ return err;
}
Q_ASSERT(obj);
@@ -1051,7 +1097,7 @@ QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScript
QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 3)
- return engine->nullValue();
+ return ctxt->throwError("Qt.vector(): Invalid arguments");
qsreal x = ctxt->argument(0).toNumber();
qsreal y = ctxt->argument(1).toNumber();
qsreal z = ctxt->argument(2).toNumber();
@@ -1062,7 +1108,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptE
{
int argCount = ctxt->argumentCount();
if(argCount == 0 || argCount > 2)
- return engine->nullValue();
+ return ctxt->throwError("Qt.formatDate(): Invalid arguments");
QDate date = ctxt->argument(0).toDateTime().date();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
@@ -1072,8 +1118,9 @@ QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptE
return engine->newVariant(qVariantFromValue(date.toString(format)));
} else if (ctxt->argument(1).isNumber()) {
enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32());
- } else
- return engine->nullValue();
+ } else {
+ return ctxt->throwError("Qt.formatDate(): Invalid date format");
+ }
}
return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
}
@@ -1082,7 +1129,7 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE
{
int argCount = ctxt->argumentCount();
if(argCount == 0 || argCount > 2)
- return engine->nullValue();
+ return ctxt->throwError("Qt.formatTime(): Invalid arguments");
QTime date = ctxt->argument(0).toDateTime().time();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
@@ -1092,8 +1139,9 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE
return engine->newVariant(qVariantFromValue(date.toString(format)));
} else if (ctxt->argument(1).isNumber()) {
enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32());
- } else
- return engine->nullValue();
+ } else {
+ return ctxt->throwError("Qt.formatTime(): Invalid time format");
+ }
}
return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
}
@@ -1102,7 +1150,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr
{
int argCount = ctxt->argumentCount();
if(argCount == 0 || argCount > 2)
- return engine->nullValue();
+ return ctxt->throwError("Qt.formatDateTime(): Invalid arguments");
QDateTime date = ctxt->argument(0).toDateTime();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
@@ -1112,8 +1160,9 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr
return engine->newVariant(qVariantFromValue(date.toString(format)));
} else if (ctxt->argument(1).isNumber()) {
enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32());
- } else
- return engine->nullValue();
+ } else {
+ return ctxt->throwError("Qt.formatDateTime(): Invalid datetime formate");
+ }
}
return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
}
@@ -1122,14 +1171,20 @@ QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine
{
int argCount = ctxt->argumentCount();
if(argCount < 3 || argCount > 4)
- return engine->nullValue();
+ return ctxt->throwError("Qt.rgba(): Invalid arguments");
qsreal r = ctxt->argument(0).toNumber();
qsreal g = ctxt->argument(1).toNumber();
qsreal b = ctxt->argument(2).toNumber();
qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
- if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1 || a < 0 || a > 1)
- return engine->nullValue();
+ if (r < 0.0) r=0.0;
+ if (r > 1.0) r=1.0;
+ if (g < 0.0) g=0.0;
+ if (g > 1.0) g=1.0;
+ if (b < 0.0) b=0.0;
+ if (b > 1.0) b=1.0;
+ if (a < 0.0) a=0.0;
+ if (a > 1.0) a=1.0;
return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromRgbF(r, g, b, a)));
}
@@ -1138,14 +1193,20 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine
{
int argCount = ctxt->argumentCount();
if(argCount < 3 || argCount > 4)
- return engine->nullValue();
+ return ctxt->throwError("Qt.hsla(): Invalid arguments");
qsreal h = ctxt->argument(0).toNumber();
qsreal s = ctxt->argument(1).toNumber();
qsreal l = ctxt->argument(2).toNumber();
qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
- if (h < 0 || h > 1 || s < 0 || s > 1 || l < 0 || l > 1 || a < 0 || a > 1)
- return engine->nullValue();
+ if (h < 0.0) h=0.0;
+ if (h > 1.0) h=1.0;
+ if (s < 0.0) s=0.0;
+ if (s > 1.0) s=1.0;
+ if (l < 0.0) l=0.0;
+ if (l > 1.0) l=1.0;
+ if (a < 0.0) a=0.0;
+ if (a > 1.0) a=1.0;
return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromHslF(h, s, l, a)));
}
@@ -1153,7 +1214,7 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 4)
- return engine->nullValue();
+ return ctxt->throwError("Qt.rect(): Invalid arguments");
qsreal x = ctxt->argument(0).toNumber();
qsreal y = ctxt->argument(1).toNumber();
@@ -1169,7 +1230,7 @@ QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 2)
- return engine->nullValue();
+ return ctxt->throwError("Qt.point(): Invalid arguments");
qsreal x = ctxt->argument(0).toNumber();
qsreal y = ctxt->argument(1).toNumber();
return qScriptValueFromValue(engine, qVariantFromValue(QPointF(x, y)));
@@ -1178,7 +1239,7 @@ QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngin
QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 2)
- return engine->nullValue();
+ return ctxt->throwError("Qt.size(): Invalid arguments");
qsreal w = ctxt->argument(0).toNumber();
qsreal h = ctxt->argument(1).toNumber();
return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h)));
@@ -1187,7 +1248,7 @@ QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 1)
- return engine->nullValue();
+ return ctxt->throwError("Qt.lighter(): Invalid arguments");
QVariant v = ctxt->argument(0).toVariant();
QColor color;
if (v.userType() == QVariant::Color)
@@ -1206,7 +1267,7 @@ QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEng
QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 1)
- return engine->nullValue();
+ return ctxt->throwError("Qt.darker(): Invalid arguments");
QVariant v = ctxt->argument(0).toVariant();
QColor color;
if (v.userType() == QVariant::Color)
@@ -1225,21 +1286,20 @@ QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngi
QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
{
if(ctxt->argumentCount() < 1)
- return e->newVariant(QVariant(false));
+ return QScriptValue(e, false);
bool ret = false;
#ifndef QT_NO_DESKTOPSERVICES
ret = QDesktopServices::openUrl(QUrl(ctxt->argument(0).toString()));
#endif
- return e->newVariant(QVariant(ret));
+ return QScriptValue(e, ret);
}
QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
{
- QByteArray data;
-
- if (ctxt->argumentCount() >= 1)
- data = ctxt->argument(0).toString().toUtf8();
+ if (ctxt->argumentCount() != 1)
+ return ctxt->throwError("Qt.md5(): Invalid arguments");
+ QByteArray data = ctxt->argument(0).toString().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
return QScriptValue(QLatin1String(result.toHex()));
@@ -1247,20 +1307,20 @@ QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
{
- QByteArray data;
+ if (ctxt->argumentCount() != 1)
+ return ctxt->throwError("Qt.btoa(): Invalid arguments");
- if (ctxt->argumentCount() >= 1)
- data = ctxt->argument(0).toString().toUtf8();
+ QByteArray data = ctxt->argument(0).toString().toUtf8();
return QScriptValue(QLatin1String(data.toBase64()));
}
QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
{
- QByteArray data;
+ if (ctxt->argumentCount() != 1)
+ return ctxt->throwError("Qt.atob(): Invalid arguments");
- if (ctxt->argumentCount() >= 1)
- data = ctxt->argument(0).toString().toUtf8();
+ QByteArray data = ctxt->argument(0).toString().toUtf8();
return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
}
@@ -1284,23 +1344,82 @@ QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScript
return e->newVariant(QVariant(true));
}
-void QDeclarativeEnginePrivate::sendQuit ()
+void QDeclarativeEnginePrivate::sendQuit()
{
Q_Q(QDeclarativeEngine);
emit q->quit();
}
+static void dumpwarning(const QDeclarativeError &error)
+{
+ qWarning().nospace() << qPrintable(error.toString());
+}
+
+static void dumpwarning(const QList<QDeclarativeError> &errors)
+{
+ for (int ii = 0; ii < errors.count(); ++ii)
+ dumpwarning(errors.at(ii));
+}
+
+void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
+{
+ Q_Q(QDeclarativeEngine);
+ q->warnings(QList<QDeclarativeError>() << error);
+ if (outputWarningsToStdErr)
+ dumpwarning(error);
+}
+
+void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
+{
+ Q_Q(QDeclarativeEngine);
+ q->warnings(errors);
+ if (outputWarningsToStdErr)
+ dumpwarning(errors);
+}
+
+void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
+{
+ if (engine)
+ QDeclarativeEnginePrivate::get(engine)->warning(error);
+ else
+ dumpwarning(error);
+}
+
+void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
+{
+ if (engine)
+ QDeclarativeEnginePrivate::get(engine)->warning(error);
+ else
+ dumpwarning(error);
+}
+
+void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
+{
+ if (engine)
+ engine->warning(error);
+ else
+ dumpwarning(error);
+}
+
+void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
+{
+ if (engine)
+ engine->warning(error);
+ else
+ dumpwarning(error);
+}
+
QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
{
QDeclarativeEnginePrivate *qe = get (e);
- qe->sendQuit ();
+ qe->sendQuit();
return QScriptValue();
}
QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 2)
- return engine->nullValue();
+ return ctxt->throwError("Qt.tint(): Invalid arguments");
//get color
QVariant v = ctxt->argument(0).toVariant();
QColor color;
@@ -1350,7 +1469,7 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
{
if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
- QDeclarativeListReferencePrivate *p =
+ QDeclarativeListReferencePrivate *p =
QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
if (p->object) {
return listClass->newList(p->property, p->propertyType);
@@ -1383,7 +1502,7 @@ QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val
QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
if (dc == objectClass)
return QVariant::fromValue(objectClass->toQObject(val));
- else if (dc == valueTypeClass)
+ else if (dc == valueTypeClass)
return valueTypeClass->toVariant(val);
else if (dc == contextClass)
return QVariant();
@@ -1410,7 +1529,6 @@ static QString toLocalFileOrQrc(const QUrl& url)
if (url.scheme() == QLatin1String("qrc")) {
if (url.authority().isEmpty())
return QLatin1Char(':') + url.path();
- qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known.";
return QString();
}
return url.toLocalFile();
@@ -1595,7 +1713,7 @@ public:
if (importType == QDeclarativeScriptParser::Import::Library) {
url.replace(QLatin1Char('.'), QLatin1Char('/'));
bool found = false;
- QString dir;
+ QString dir;
foreach (const QString &p,
@@ -1620,7 +1738,7 @@ public:
found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin);
if (!found) {
if (errorString) {
- bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), 0, 0);
+ bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1);
if (anyversion)
*errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
else
@@ -1773,8 +1891,8 @@ static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine,
int minor = set.minversions.at(ii);
foreach (QDeclarativeType *type, types) {
- if (type->qmlTypeName().startsWith(base) &&
- type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
+ if (type->qmlTypeName().startsWith(base) &&
+ type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
type->availableInVersion(major,minor))
{
QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length()));
@@ -1943,7 +2061,8 @@ QStringList QDeclarativeEngine::pluginPathList() const
/*!
Sets the list of directories where the engine searches for
- native plugins for imported modules (referenced in the \c qmldir file).
+ native plugins for imported modules (referenced in the \c qmldir file)
+ to \a paths.
By default, the list contains only \c ., i.e. the engine searches
in the directory of the \c qmldir file itself.
@@ -1961,6 +2080,8 @@ void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
Imports the plugin named \a filePath with the \a uri provided.
Returns true if the plugin was successfully imported; otherwise returns false.
+ On failure and if non-null, *\a errorString will be set to a message describing the failure.
+
The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
*/
bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index 7b058ea..01487f5 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -46,6 +46,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qmap.h>
#include <QtScript/qscriptvalue.h>
+#include <QtDeclarative/qdeclarativeerror.h>
QT_BEGIN_HEADER
@@ -102,6 +103,9 @@ public:
QUrl baseUrl() const;
void setBaseUrl(const QUrl &);
+ bool outputWarningsToStandardError() const;
+ void setOutputWarningsToStandardError(bool);
+
static QDeclarativeContext *contextForObject(const QObject *);
static void setContextForObject(QObject *, QDeclarativeContext *);
@@ -110,9 +114,11 @@ public:
static ObjectOwnership objectOwnership(QObject *);
Q_SIGNALS:
- void quit ();
+ void quit();
+ void warnings(const QList<QDeclarativeError> &warnings);
private:
+ Q_DISABLE_COPY(QDeclarativeEngine)
Q_DECLARE_PRIVATE(QDeclarativeEngine)
};
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index b3bba43..f6b9bcb 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -162,6 +162,8 @@ public:
QDeclarativeExpression *currentExpression;
bool isDebugging;
+ bool outputWarningsToStdErr;
+
struct ImportedNamespace;
QDeclarativeContextScriptClass *contextClass;
QDeclarativeContextData *sharedContext;
@@ -311,7 +313,13 @@ public:
QScriptValue scriptValueFromVariant(const QVariant &);
QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid);
- void sendQuit ();
+ void sendQuit();
+ void warning(const QDeclarativeError &);
+ void warning(const QList<QDeclarativeError> &);
+ static void warning(QDeclarativeEngine *, const QDeclarativeError &);
+ static void warning(QDeclarativeEngine *, const QList<QDeclarativeError> &);
+ static void warning(QDeclarativeEnginePrivate *, const QDeclarativeError &);
+ static void warning(QDeclarativeEnginePrivate *, const QList<QDeclarativeError> &);
static QScriptValue qmlScriptObject(QObject*, QDeclarativeEngine*);
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index 578733c..69e42f8 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -308,8 +308,6 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
QByteArray type;
ds >> type;
- //qDebug() << "QDeclarativeEngineDebugServer::messageReceived()" << type;
-
if (type == "LIST_ENGINES") {
int queryId;
ds >> queryId;
@@ -418,7 +416,7 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
if (object && context) {
QDeclarativeExpression exprObj(context, expr, object);
bool undefined = false;
- QVariant value = exprObj.value(&undefined);
+ QVariant value = exprObj.evaluate(&undefined);
if (undefined)
result = QLatin1String("<undefined>");
else
diff --git a/src/declarative/qml/qdeclarativeerror.cpp b/src/declarative/qml/qdeclarativeerror.cpp
index 7e8aac0..8717f56 100644
--- a/src/declarative/qml/qdeclarativeerror.cpp
+++ b/src/declarative/qml/qdeclarativeerror.cpp
@@ -49,8 +49,27 @@ QT_BEGIN_NAMESPACE
/*!
\class QDeclarativeError
- \since 4.7
- \brief The QDeclarativeError class encapsulates a QML error
+ \since 4.7
+ \brief The QDeclarativeError class encapsulates a QML error.
+
+ QDeclarativeError includes a textual description of the error, as well
+ as location information (the file, line, and column). The toString()
+ method creates a single-line, human-readable string containing all of
+ this information, for example:
+ \code
+ file:///home/user/test.qml:7:8: Invalid property assignment: double expected
+ \endcode
+
+ You can use qDebug() or qWarning() to output errors to the console. This method
+ will attempt to open the file indicated by the error
+ and include additional contextual information.
+ \code
+ file:///home/user/test.qml:7:8: Invalid property assignment: double expected
+ y: "hello"
+ ^
+ \endcode
+
+ \sa QDeclarativeView::errors(), QDeclarativeComponent::errors()
*/
class QDeclarativeErrorPrivate
{
@@ -69,7 +88,7 @@ QDeclarativeErrorPrivate::QDeclarativeErrorPrivate()
}
/*!
- Create an empty error object.
+ Creates an empty error object.
*/
QDeclarativeError::QDeclarativeError()
: d(0)
@@ -77,7 +96,7 @@ QDeclarativeError::QDeclarativeError()
}
/*!
- Create a copy of \a other.
+ Creates a copy of \a other.
*/
QDeclarativeError::QDeclarativeError(const QDeclarativeError &other)
: d(0)
@@ -86,7 +105,7 @@ QDeclarativeError::QDeclarativeError(const QDeclarativeError &other)
}
/*!
- Assign \a other to this error object.
+ Assigns \a other to this error object.
*/
QDeclarativeError &QDeclarativeError::operator=(const QDeclarativeError &other)
{
@@ -112,7 +131,7 @@ QDeclarativeError::~QDeclarativeError()
}
/*!
- Return true if this error is valid, otherwise false.
+ Returns true if this error is valid, otherwise false.
*/
bool QDeclarativeError::isValid() const
{
@@ -120,7 +139,7 @@ bool QDeclarativeError::isValid() const
}
/*!
- Return the url for the file that caused this error.
+ Returns the url for the file that caused this error.
*/
QUrl QDeclarativeError::url() const
{
@@ -129,7 +148,7 @@ QUrl QDeclarativeError::url() const
}
/*!
- Set the \a url for the file that caused this error.
+ Sets the \a url for the file that caused this error.
*/
void QDeclarativeError::setUrl(const QUrl &url)
{
@@ -138,7 +157,7 @@ void QDeclarativeError::setUrl(const QUrl &url)
}
/*!
- Return the error description.
+ Returns the error description.
*/
QString QDeclarativeError::description() const
{
@@ -147,7 +166,7 @@ QString QDeclarativeError::description() const
}
/*!
- Set the error \a description.
+ Sets the error \a description.
*/
void QDeclarativeError::setDescription(const QString &description)
{
@@ -156,7 +175,7 @@ void QDeclarativeError::setDescription(const QString &description)
}
/*!
- Return the error line number.
+ Returns the error line number.
*/
int QDeclarativeError::line() const
{
@@ -165,7 +184,7 @@ int QDeclarativeError::line() const
}
/*!
- Set the error \a line number.
+ Sets the error \a line number.
*/
void QDeclarativeError::setLine(int line)
{
@@ -174,7 +193,7 @@ void QDeclarativeError::setLine(int line)
}
/*!
- Return the error column number.
+ Returns the error column number.
*/
int QDeclarativeError::column() const
{
@@ -183,7 +202,7 @@ int QDeclarativeError::column() const
}
/*!
- Set the error \a column number.
+ Sets the error \a column number.
*/
void QDeclarativeError::setColumn(int column)
{
@@ -192,14 +211,20 @@ void QDeclarativeError::setColumn(int column)
}
/*!
- Return the error as a human readable string.
+ Returns the error as a human readable string.
*/
QString QDeclarativeError::toString() const
{
QString rv;
- rv = url().toString() + QLatin1Char(':') + QString::number(line());
- if(column() != -1)
- rv += QLatin1Char(':') + QString::number(column());
+ if (url().isEmpty()) {
+ rv = QLatin1String("<Unknown File>");
+ } else if (line() != -1) {
+ rv = url().toString() + QLatin1Char(':') + QString::number(line());
+ if(column() != -1)
+ rv += QLatin1Char(':') + QString::number(column());
+ } else {
+ rv = url().toString();
+ }
rv += QLatin1String(": ") + description();
@@ -210,7 +235,7 @@ QString QDeclarativeError::toString() const
\relates QDeclarativeError
\fn QDebug operator<<(QDebug debug, const QDeclarativeError &error)
- Output a human readable version of \a error to \a debug.
+ Outputs a human readable version of \a error to \a debug.
*/
QDebug operator<<(QDebug debug, const QDeclarativeError &error)
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 05240a2..f561a7e 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -479,18 +479,18 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU
}
/*!
- Returns the value of the expression, or an invalid QVariant if the
- expression is invalid or has an error.
+ Evaulates the expression, returning the result of the evaluation,
+ or an invalid QVariant if the expression is invalid or has an error.
- \a isUndefined is set to true if the expression resulted in an
+ \a valueIsUndefined is set to true if the expression resulted in an
undefined value.
\sa hasError(), error()
*/
-QVariant QDeclarativeExpression::value(bool *isUndefined)
+QVariant QDeclarativeExpression::evaluate(bool *valueIsUndefined)
{
Q_D(QDeclarativeExpression);
- return d->value(0, isUndefined);
+ return d->value(0, valueIsUndefined);
}
/*!
@@ -569,7 +569,7 @@ QObject *QDeclarativeExpression::scopeObject() const
}
/*!
- Returns true if the last call to value() resulted in an error,
+ Returns true if the last call to evaluate() resulted in an error,
otherwise false.
\sa error(), clearError()
@@ -593,7 +593,7 @@ void QDeclarativeExpression::clearError()
}
/*!
- Return any error from the last call to value(). If there was no error,
+ Return any error from the last call to evaluate(). If there was no error,
this returns an invalid QDeclarativeError instance.
\sa hasError(), clearError()
@@ -606,10 +606,9 @@ QDeclarativeError QDeclarativeExpression::error() const
}
/*! \internal */
-void QDeclarativeExpression::__q_notify()
+void QDeclarativeExpressionPrivate::_q_notify()
{
- Q_D(QDeclarativeExpression);
- d->emitValueChanged();
+ emitValueChanged();
}
void QDeclarativeExpressionPrivate::clearGuards()
@@ -625,7 +624,7 @@ void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEn
static int notifyIdx = -1;
if (notifyIdx == -1)
- notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()");
+ notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
if (properties.count() != data->guardListLength) {
QDeclarativeNotifierEndpoint *newGuardList =
@@ -695,14 +694,13 @@ void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEn
if (!outputWarningHeader) {
outputWarningHeader = true;
qWarning() << "QDeclarativeExpression: Expression" << q->expression()
- << "depends on non-NOTIFYable properties:";
+ << "depends on non-NOTIFYable properties:";
}
const QMetaObject *metaObj = property.object->metaObject();
QMetaProperty metaProp = metaObj->property(property.coreIndex);
- qWarning().nospace() << " " << metaObj->className()
- << "::" << metaProp.name();
+ qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name();
}
}
}
@@ -712,7 +710,7 @@ void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEn
Emitted each time the expression value changes from the last time it was
evaluated. The expression must have been evaluated at least once (by
- calling QDeclarativeExpression::value()) before this signal will be emitted.
+ calling QDeclarativeExpression::evaluate()) before this signal will be emitted.
*/
void QDeclarativeExpressionPrivate::emitValueChanged()
@@ -772,3 +770,4 @@ bool QDeclarativeAbstractExpression::isValid() const
QT_END_NAMESPACE
+#include <moc_qdeclarativeexpression.cpp>
diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h
index 35d6949..6c72e4d 100644
--- a/src/declarative/qml/qdeclarativeexpression.h
+++ b/src/declarative/qml/qdeclarativeexpression.h
@@ -86,7 +86,7 @@ public:
void clearError();
QDeclarativeError error() const;
- QVariant value(bool *isUndefined = 0);
+ QVariant evaluate(bool *valueIsUndefined = 0);
Q_SIGNALS:
void valueChanged();
@@ -97,13 +97,12 @@ protected:
QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc,
QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd);
-private Q_SLOTS:
- void __q_notify();
-
private:
QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *);
+ Q_DISABLE_COPY(QDeclarativeExpression)
Q_DECLARE_PRIVATE(QDeclarativeExpression)
+ Q_PRIVATE_SLOT(d_func(), void _q_notify())
friend class QDeclarativeDebugger;
friend class QDeclarativeContext;
friend class QDeclarativeVME;
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h
index d39aa2c..4ff3162 100644
--- a/src/declarative/qml/qdeclarativeexpression_p.h
+++ b/src/declarative/qml/qdeclarativeexpression_p.h
@@ -164,6 +164,7 @@ public:
return expr->q_func();
}
+ void _q_notify();
virtual void emitValueChanged();
static void exceptionToError(QScriptEngine *, QDeclarativeError &);
diff --git a/src/declarative/qml/qdeclarativeextensionplugin.cpp b/src/declarative/qml/qdeclarativeextensionplugin.cpp
index 762c642d..863bfc4 100644
--- a/src/declarative/qml/qdeclarativeextensionplugin.cpp
+++ b/src/declarative/qml/qdeclarativeextensionplugin.cpp
@@ -59,6 +59,11 @@ QT_BEGIN_NAMESPACE
function, and exporting the class using the Q_EXPORT_PLUGIN2()
macro.
+ QML extension plugins can be used to provide either application-specific or
+ library-like plugins. Library plugins should limit themselves to registering types,
+ as any manipulation of the engine's root context may cause conflicts
+ or other issues in the library user's code.
+
See \l {Extending QML in C++} for details how to write a QML extension plugin.
See \l {How to Create Qt Plugins} for general Qt plugin documentation.
@@ -85,7 +90,7 @@ QDeclarativeExtensionPlugin::QDeclarativeExtensionPlugin(QObject *parent)
}
/*!
- Destructor.
+ Destroys the plugin.
*/
QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin()
{
@@ -94,7 +99,9 @@ QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin()
/*!
\fn void QDeclarativeExtensionPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
- Initializes the extension from the \a uri using the \a engine.
+ Initializes the extension from the \a uri using the \a engine. Here an application
+ plugin might, for example, expose some data or objects to QML,
+ as context properties on the engine's root context.
*/
void QDeclarativeExtensionPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
diff --git a/src/declarative/qml/qdeclarativeextensionplugin.h b/src/declarative/qml/qdeclarativeextensionplugin.h
index 8095ec7..8a9378a 100644
--- a/src/declarative/qml/qdeclarativeextensionplugin.h
+++ b/src/declarative/qml/qdeclarativeextensionplugin.h
@@ -64,6 +64,9 @@ public:
virtual void registerTypes(const char *uri) = 0;
virtual void initializeEngine(QDeclarativeEngine *engine, const char *uri);
+
+private:
+ Q_DISABLE_COPY(QDeclarativeExtensionPlugin)
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp
index b992b9f..4be3472 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.cpp
+++ b/src/declarative/qml/qdeclarativeimageprovider.cpp
@@ -45,31 +45,39 @@ QT_BEGIN_NAMESPACE
/*!
\class QDeclarativeImageProvider
- \brief The QDeclarativeImageProvider class provides an interface for threaded image requests.
+ \since 4.7
+ \brief The QDeclarativeImageProvider class provides an interface for threaded image requests in QML.
- Note: the request() method may be called by multiple threads, so ensure the
+ QDeclarativeImageProvider can be used by a QDeclarativeEngine to provide images to QML asynchronously.
+ The image request will be run in a low priority thread, allowing potentially costly image
+ loading to be done in the background, without affecting the performance of the UI.
+
+ See the QDeclarativeEngine::addImageProvider() documentation for an
+ example of how a custom QDeclarativeImageProvider can be constructed and used.
+
+ \note the request() method may be called by multiple threads, so ensure the
implementation of this method is reentrant.
\sa QDeclarativeEngine::addImageProvider()
*/
/*!
- The destructor is virtual.
+ Destroys the image provider.
*/
QDeclarativeImageProvider::~QDeclarativeImageProvider()
{
}
/*!
- \fn QImage QDeclarativeImageProvider::request(const QString &id, QSize *size, const QSize& requested_size)
+ \fn QImage QDeclarativeImageProvider::request(const QString &id, QSize *size, const QSize& requestedSize)
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.
+ If \a requestedSize is a valid size, the image returned should be of that size.
- In any case, \a size must be set to the (original) size of the image.
+ In all cases, \a size must be set to the original size of the image.
- Note: this method may be called by multiple threads, so ensure the
+ \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 50b73fe..cc9c9af 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, QSize *size, const QSize& requested_size) = 0;
+ virtual QImage request(const QString &id, QSize *size, const QSize& requestedSize) = 0;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp
index 0a4352f..ffed14e 100644
--- a/src/declarative/qml/qdeclarativeinfo.cpp
+++ b/src/declarative/qml/qdeclarativeinfo.cpp
@@ -45,6 +45,7 @@
#include "qdeclarativecontext.h"
#include "private/qdeclarativecontext_p.h"
#include "private/qdeclarativemetatype_p.h"
+#include "private/qdeclarativeengine_p.h"
#include <QCoreApplication>
@@ -77,51 +78,98 @@ QT_BEGIN_NAMESPACE
\endcode
*/
-QDeclarativeInfo::QDeclarativeInfo(const QObject *object)
-: QDebug(QtWarningMsg)
+struct QDeclarativeInfoPrivate
{
- QString pos = QLatin1String("QML");
- if (object) {
- pos += QLatin1Char(' ');
-
- QString typeName;
- QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
- if (type) {
- typeName = QLatin1String(type->qmlTypeName());
- int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
- if (lastSlash != -1)
- typeName = typeName.mid(lastSlash+1);
- } else {
- typeName = QString::fromUtf8(object->metaObject()->className());
- int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
- if (marker != -1)
- typeName = typeName.left(marker);
- }
+ QDeclarativeInfoPrivate() : ref (1), object(0) {}
- pos += typeName;
- }
- QDeclarativeData *ddata = object?QDeclarativeData::get(object):0;
- pos += QLatin1String(" (");
- if (ddata) {
- if (ddata->outerContext && !ddata->outerContext->url.isEmpty()) {
- pos += ddata->outerContext->url.toString();
- pos += QLatin1Char(':');
- pos += QString::number(ddata->lineNumber);
- pos += QLatin1Char(':');
- pos += QString::number(ddata->columnNumber);
- } else {
- pos += QCoreApplication::translate("QDeclarativeInfo","unknown location");
- }
- } else {
- pos += QCoreApplication::translate("QDeclarativeInfo","unknown location");
- }
- pos += QLatin1Char(')');
- *this << pos;
+ int ref;
+ const QObject *object;
+ QString buffer;
+ QList<QDeclarativeError> errors;
+};
+
+QDeclarativeInfo::QDeclarativeInfo(QDeclarativeInfoPrivate *p)
+: QDebug(&p->buffer), d(p)
+{
nospace();
}
+QDeclarativeInfo::QDeclarativeInfo(const QDeclarativeInfo &other)
+: QDebug(other), d(other.d)
+{
+ d->ref++;
+}
+
QDeclarativeInfo::~QDeclarativeInfo()
{
+ if (0 == --d->ref) {
+ QList<QDeclarativeError> errors = d->errors;
+
+ QDeclarativeEngine *engine = 0;
+
+ if (!d->buffer.isEmpty()) {
+ QDeclarativeError error;
+
+ QObject *object = const_cast<QObject *>(d->object);
+
+ if (object) {
+ engine = qmlEngine(d->object);
+ QString typeName;
+ QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
+ if (type) {
+ typeName = QLatin1String(type->qmlTypeName());
+ int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ typeName = typeName.mid(lastSlash+1);
+ } else {
+ typeName = QString::fromUtf8(object->metaObject()->className());
+ int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
+ if (marker != -1)
+ typeName = typeName.left(marker);
+ }
+
+ d->buffer.prepend(QLatin1String("QML ") + typeName + QLatin1String(": "));
+
+ QDeclarativeData *ddata = QDeclarativeData::get(object, false);
+ if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) {
+ error.setUrl(ddata->outerContext->url);
+ error.setLine(ddata->lineNumber);
+ error.setColumn(ddata->columnNumber);
+ }
+ }
+
+ error.setDescription(d->buffer);
+
+ errors.prepend(error);
+ }
+
+ QDeclarativeEnginePrivate::warning(engine, errors);
+
+ delete d;
+ }
+}
+
+QDeclarativeInfo qmlInfo(const QObject *me)
+{
+ QDeclarativeInfoPrivate *d = new QDeclarativeInfoPrivate;
+ d->object = me;
+ return QDeclarativeInfo(d);
+}
+
+QDeclarativeInfo qmlInfo(const QObject *me, const QDeclarativeError &error)
+{
+ QDeclarativeInfoPrivate *d = new QDeclarativeInfoPrivate;
+ d->object = me;
+ d->errors << error;
+ return QDeclarativeInfo(d);
+}
+
+QDeclarativeInfo qmlInfo(const QObject *me, const QList<QDeclarativeError> &errors)
+{
+ QDeclarativeInfoPrivate *d = new QDeclarativeInfoPrivate;
+ d->object = me;
+ d->errors = errors;
+ return QDeclarativeInfo(d);
}
diff --git a/src/declarative/qml/qdeclarativeinfo.h b/src/declarative/qml/qdeclarativeinfo.h
index 8f69f73..2ac28f4 100644
--- a/src/declarative/qml/qdeclarativeinfo.h
+++ b/src/declarative/qml/qdeclarativeinfo.h
@@ -43,6 +43,8 @@
#define QDECLARATIVEINFO_H
#include <QtCore/qdebug.h>
+#include <QtCore/qurl.h>
+#include <QtDeclarative/qdeclarativeerror.h>
QT_BEGIN_HEADER
@@ -50,10 +52,11 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QDeclarativeInfoPrivate;
class Q_DECLARATIVE_EXPORT QDeclarativeInfo : public QDebug
{
public:
- QDeclarativeInfo(const QObject *);
+ QDeclarativeInfo(const QDeclarativeInfo &);
~QDeclarativeInfo();
inline QDeclarativeInfo &operator<<(QChar t) { QDebug::operator<<(t); return *this; }
@@ -78,12 +81,20 @@ public:
inline QDeclarativeInfo &operator<<(const void * t) { QDebug::operator<<(t); return *this; }
inline QDeclarativeInfo &operator<<(QTextStreamFunction f) { QDebug::operator<<(f); return *this; }
inline QDeclarativeInfo &operator<<(QTextStreamManipulator m) { QDebug::operator<<(m); return *this; }
+ inline QDeclarativeInfo &operator<<(const QUrl &t) { static_cast<QDebug &>(*this) << t; return *this; }
+
+private:
+ friend Q_DECLARATIVE_EXPORT QDeclarativeInfo qmlInfo(const QObject *me);
+ friend Q_DECLARATIVE_EXPORT QDeclarativeInfo qmlInfo(const QObject *me, const QDeclarativeError &error);
+ friend Q_DECLARATIVE_EXPORT QDeclarativeInfo qmlInfo(const QObject *me, const QList<QDeclarativeError> &errors);
+
+ QDeclarativeInfo(QDeclarativeInfoPrivate *);
+ QDeclarativeInfoPrivate *d;
};
-Q_DECLARATIVE_EXPORT inline QDeclarativeInfo qmlInfo(const QObject *me)
-{
- return QDeclarativeInfo(me);
-}
+Q_DECLARATIVE_EXPORT QDeclarativeInfo qmlInfo(const QObject *me);
+Q_DECLARATIVE_EXPORT QDeclarativeInfo qmlInfo(const QObject *me, const QDeclarativeError &error);
+Q_DECLARATIVE_EXPORT QDeclarativeInfo qmlInfo(const QObject *me, const QList<QDeclarativeError> &errors);
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp
index d88d06a..99f1cc8 100644
--- a/src/declarative/qml/qdeclarativeinstruction.cpp
+++ b/src/declarative/qml/qdeclarativeinstruction.cpp
@@ -149,9 +149,6 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
case QDeclarativeInstruction::StoreSignal:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value << "\t\t" << primitives.at(instr->storeSignal.value);
break;
- case QDeclarativeInstruction::StoreScript:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value;
- break;
case QDeclarativeInstruction::StoreImportedScript:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value;
break;
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index e8287c0..c09b157 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -121,7 +121,6 @@ public:
StoreInterface, /* storeObject */
StoreSignal, /* storeSignal */
- StoreScript, /* storeScript */
StoreImportedScript, /* storeScript */
StoreScriptString, /* storeScriptString */
diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp
index 45b8cd7..31ef4c2 100644
--- a/src/declarative/qml/qdeclarativelist.cpp
+++ b/src/declarative/qml/qdeclarativelist.cpp
@@ -87,9 +87,10 @@ void QDeclarativeListReferencePrivate::release()
/*!
\class QDeclarativeListReference
+\since 4.7
\brief The QDeclarativeListReference class allows the manipulation of QDeclarativeListProperty properties.
-QDeclarativeListReference allows programs to read from, and assign values to a QML list property in a
+QDeclarativeListReference allows C++ programs to read from, and assign values to a QML list property in a
simple and type safe way. A QDeclarativeListReference can be created by passing an object and property
name or through a QDeclarativeProperty instance. These two are equivalant:
@@ -304,6 +305,7 @@ int QDeclarativeListReference::count() const
/*!
\class QDeclarativeListProperty
+\since 4.7
\brief The QDeclarativeListProperty class allows applications to explose list-like
properties to QML.
@@ -313,10 +315,10 @@ The use of a list property from QML looks like this:
\code
FruitBasket {
fruit: [
- Apple {},
- Orange{},
- Banana {}
- ]
+ Apple {},
+ Orange{},
+ Banana{}
+ ]
}
\endcode
@@ -336,6 +338,9 @@ Q_PROPERTY(QDeclarativeListProperty<Fruit> fruit READ fruit);
QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
\c {Apple}, \c {Orange} and \c {Banana} all derive from.
+
+\note QDeclarativeListProperty can only be used for lists of QObject-derived object pointers.
+
*/
/*!
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index 7b71608..d9ea8dc 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -99,8 +99,12 @@ struct QDeclarativeMetaTypeData
StringConverters stringConverters;
struct ModuleInfo {
- ModuleInfo(int maj, int min) : vmajor(maj), vminor(min) {}
- int vmajor, vminor;
+ ModuleInfo(int major, int minor)
+ : vmajor_min(major), vminor_min(minor), vmajor_max(major), vminor_max(minor) {}
+ ModuleInfo(int major_min, int minor_min, int major_max, int minor_max)
+ : vmajor_min(major_min), vminor_min(minor_min), vmajor_max(major_max), vminor_max(minor_max) {}
+ int vmajor_min, vminor_min;
+ int vmajor_max, vminor_max;
};
typedef QHash<QByteArray, ModuleInfo> ModuleInfoHash;
ModuleInfoHash modules;
@@ -134,6 +138,7 @@ public:
int m_allocationSize;
void (*m_newFunc)(void *);
+ QString m_noCreationReason;
const QMetaObject *m_baseMetaObject;
QDeclarativeAttachedPropertiesFunc m_attachedPropertiesFunc;
@@ -186,6 +191,7 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe
d->m_listId = type.listId;
d->m_allocationSize = type.objectSize;
d->m_newFunc = type.create;
+ d->m_noCreationReason = type.noCreationReason;
d->m_baseMetaObject = type.metaObject;
d->m_attachedPropertiesFunc = type.attachedPropertiesFunction;
d->m_attachedPropertiesType = type.attachedPropertiesMetaObject;
@@ -221,6 +227,76 @@ bool QDeclarativeType::availableInVersion(int vmajor, int vminor) const
return vmajor > d->m_version_maj || (vmajor == d->m_version_maj && vminor >= d->m_version_min);
}
+static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
+ const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
+{
+ // Clone Q_CLASSINFO
+ for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
+ QMetaClassInfo info = mo->classInfo(ii);
+
+ int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
+ if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
+ // Skip
+ } else {
+ builder.addClassInfo(info.name(), info.value());
+ }
+ }
+
+ // Clone Q_PROPERTY
+ for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
+ QMetaProperty property = mo->property(ii);
+
+ int otherIndex = ignoreEnd->indexOfProperty(property.name());
+ if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
+ builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
+ // Skip
+ } else {
+ builder.addProperty(property);
+ }
+ }
+
+ // Clone Q_METHODS
+ for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
+ QMetaMethod method = mo->method(ii);
+
+ // More complex - need to search name
+ QByteArray name = method.signature();
+ int parenIdx = name.indexOf('(');
+ if (parenIdx != -1) name = name.left(parenIdx);
+
+
+ bool found = false;
+
+ for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
+ !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount();
+ ++ii) {
+
+ QMetaMethod other = ignoreEnd->method(ii);
+ QByteArray othername = other.signature();
+ int parenIdx = othername.indexOf('(');
+ if (parenIdx != -1) othername = othername.left(parenIdx);
+
+ found = name == othername;
+ }
+
+ QMetaMethodBuilder m = builder.addMethod(method);
+ if (found) // SKIP
+ m.setAccess(QMetaMethod::Private);
+ }
+
+ // Clone Q_ENUMS
+ for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
+ QMetaEnum enumerator = mo->enumerator(ii);
+
+ int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
+ if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
+ // Skip
+ } else {
+ builder.addEnumerator(enumerator);
+ }
+ }
+}
+
void QDeclarativeTypePrivate::init() const
{
if (m_isSetup) return;
@@ -245,8 +321,9 @@ void QDeclarativeTypePrivate::init() const
QDeclarativeType *t = metaTypeData()->metaObjectToType.value(mo);
if (t) {
if (t->d->m_extFunc) {
- QMetaObject *mmo = new QMetaObject;
- *mmo = *t->d->m_extMetaObject;
+ QMetaObjectBuilder builder;
+ clone(builder, t->d->m_extMetaObject, t->d->m_baseMetaObject, m_baseMetaObject);
+ QMetaObject *mmo = builder.toMetaObject();
mmo->d.superdata = m_baseMetaObject;
if (!m_metaObjects.isEmpty())
m_metaObjects.last().metaObject->d.superdata = mmo;
@@ -318,6 +395,11 @@ QDeclarativeType::CreateFunc QDeclarativeType::createFunction() const
return d->m_newFunc;
}
+QString QDeclarativeType::noCreationReason() const
+{
+ return d->m_noCreationReason;
+}
+
int QDeclarativeType::createSize() const
{
return d->m_allocationSize;
@@ -403,10 +485,8 @@ int QDeclarativeType::index() const
int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterInterface &interface)
{
- if (interface.version > 0) {
- qWarning("Cannot mix incompatible QML versions.");
- return -1;
- }
+ if (interface.version > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QWriteLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
@@ -437,7 +517,7 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t
if (type.elementName) {
for (int ii = 0; type.elementName[ii]; ++ii) {
if (!isalnum(type.elementName[ii])) {
- qWarning("QDeclarativeMetaType: Invalid QML element name %s", type.elementName);
+ qWarning("qmlRegisterType(): Invalid QML element name \"%s\"", type.elementName);
return -1;
}
}
@@ -468,9 +548,15 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t
if (type.uri) {
QByteArray mod(type.uri);
QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(mod);
- if (it == data->modules.end()
- || ((*it).vmajor < type.versionMajor || ((*it).vmajor == type.versionMajor && (*it).vminor < type.versionMinor))) {
+ if (it == data->modules.end()) {
+ // New module
data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor));
+ } else if ((*it).vmajor_max < type.versionMajor || ((*it).vmajor_max == type.versionMajor && (*it).vminor_max < type.versionMinor)) {
+ // Newer module
+ data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo((*it).vmajor_min, (*it).vminor_min, type.versionMajor, type.versionMinor));
+ } else if ((*it).vmajor_min > type.versionMajor || ((*it).vmajor_min == type.versionMajor && (*it).vminor_min > type.versionMinor)) {
+ // Older module
+ data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor, type.versionMinor, (*it).vmajor_min, (*it).vminor_min));
}
}
@@ -478,15 +564,23 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t
}
/*
- Have any types been registered for \a module with at least versionMajor.versionMinor.
+ Have any types been registered for \a module with at least versionMajor.versionMinor, and types
+ for \a module with at most versionMajor.versionMinor.
+
+ So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10.
+
+ Passing -1 for both \a versionMajor \a versionMinor will return true if any version is installed.
*/
bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor)
{
QDeclarativeMetaTypeData *data = metaTypeData();
QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(module);
return it != data->modules.end()
- && ((*it).vmajor > versionMajor ||
- ((*it).vmajor == versionMajor && (*it).vminor >= versionMinor));
+ && ((versionMajor<0 && versionMinor<0) ||
+ (((*it).vmajor_max > versionMajor ||
+ ((*it).vmajor_max == versionMajor && (*it).vminor_max >= versionMinor))
+ && ((*it).vmajor_min < versionMajor ||
+ ((*it).vmajor_min == versionMajor && (*it).vminor_min <= versionMinor))));
}
QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok)
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index 70b7c90..bf6a700 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -123,6 +123,7 @@ public:
bool isCreatable() const;
bool isExtendedType() const;
+ QString noCreationReason() const;
bool isInterface() const;
int typeId() const;
diff --git a/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp b/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp
index 9dd7d39..b116129 100644
--- a/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp
+++ b/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp
@@ -45,8 +45,8 @@ QT_BEGIN_NAMESPACE
/*!
\class QDeclarativeNetworkAccessManagerFactory
- \since 4.7
- \brief The QDeclarativeNetworkAccessManagerFactory class provides a factory for QNetworkAccessManager
+ \since 4.7
+ \brief The QDeclarativeNetworkAccessManagerFactory class provides a factory for QNetworkAccessManager for use by a Qt Declarative engine.
QNetworkAccessManager is used for all network access by QML.
By implementing a factory it is possible to create custom
@@ -56,12 +56,17 @@ QT_BEGIN_NAMESPACE
To implement a factory, subclass QDeclarativeNetworkAccessManagerFactory and implement
the create() method.
+ To use a factory, assign it to the relevant QDeclarativeEngine using
+ QDeclarativeEngine::setNetworkAccessManagerFactory().
+
If the created QNetworkAccessManager becomes invalid, due to a
change in proxy settings, for example, call the invalidate() method.
This will cause all QNetworkAccessManagers to be recreated.
Note: the create() method may be called by multiple threads, so ensure the
implementation of this method is reentrant.
+
+ \sa QDeclarativeEngine::setNetworkAccessManagerFactory()
*/
/*!
@@ -77,6 +82,8 @@ QDeclarativeNetworkAccessManagerFactory::~QDeclarativeNetworkAccessManagerFactor
Implement this method to create a QNetworkAccessManager with \a parent.
This allows proxies, caching and cookie support to be setup appropriately.
+ This method should return a new QNetworkAccessManager each time it is called.
+
Note: this method may be called by multiple threads, so ensure the
implementation of this method is reentrant.
*/
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 5773fe6..bb5c8b7 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -59,12 +59,17 @@ Q_DECLARE_METATYPE(QScriptValue);
QT_BEGIN_NAMESPACE
struct ObjectData : public QScriptDeclarativeClass::Object {
- ObjectData(QObject *o, int t) : object(o), type(t) {}
+ ObjectData(QObject *o, int t) : object(o), type(t) {
+ if (o) {
+ QDeclarativeData *ddata = QDeclarativeData::get(object, true);
+ if (ddata) ddata->objectDataRefCount++;
+ }
+ }
virtual ~ObjectData() {
if (object && !object->parent()) {
QDeclarativeData *ddata = QDeclarativeData::get(object, false);
- if (ddata && !ddata->indestructible)
+ if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount)
object->deleteLater();
}
}
@@ -348,7 +353,13 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
if (delBinding)
delBinding->destroy();
- if (value.isUndefined() && lastData->flags & QDeclarativePropertyCache::Data::IsResettable) {
+ if (value.isNull() && lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {
+ QObject *o = 0;
+ int status = -1;
+ int flags = 0;
+ void *argv[] = { &o, 0, &status, &flags };
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty, lastData->coreIndex, argv);
+ } else 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>()) {
@@ -458,12 +469,21 @@ QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object)
cache = ddata->propertyCache;
if (!cache) {
cache = enginePrivate->cache(obj);
- if (cache && ddata) { cache->addref(); ddata->propertyCache = cache; }
+ if (cache) {
+ if (ddata) { cache->addref(); ddata->propertyCache = cache; }
+ } else {
+ // Not cachable - fall back to QMetaObject (eg. dynamic meta object)
+ // XXX QDeclarativeOpenMetaObject has a cache, so this is suboptimal.
+ // XXX This is a workaround for QTBUG-9420.
+ const QMetaObject *mo = obj->metaObject();
+ QStringList r;
+ int pc = mo->propertyCount();
+ int po = mo->propertyOffset();
+ for (int i=po; i<pc; ++i)
+ r += QString::fromUtf8(mo->property(i).name());
+ return r;
+ }
}
-
- if (!cache)
- return QStringList();
-
return cache->propertyNames();
}
diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp
index d1f209a..b38bd76 100644
--- a/src/declarative/qml/qdeclarativeparser.cpp
+++ b/src/declarative/qml/qdeclarativeparser.cpp
@@ -89,8 +89,6 @@ QDeclarativeParser::Object::~Object()
prop.first->release();
foreach(const DynamicProperty &prop, dynamicProperties)
if (prop.defaultValue) prop.defaultValue->release();
- foreach(Object *obj, scriptBlockObjects)
- obj->release();
}
void Object::setBindingBit(int b)
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index 00fc65b..0870cfb 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -160,8 +160,6 @@ namespace QDeclarativeParser
Property *defaultProperty;
QHash<QByteArray, Property *> properties;
- QList<Object *> scriptBlockObjects;
-
// Output of the compilation phase (these properties continue to exist
// in either the defaultProperty or properties members too)
void addValueProperty(Property *);
@@ -190,7 +188,9 @@ namespace QDeclarativeParser
QList<int> lineNumbers;
QList<Pragmas> pragmas;
};
+#if 0
QList<ScriptBlock> scripts;
+#endif
// The bytes to cast instances by to get to the QDeclarativeParserStatus
// interface. -1 indicates the type doesn't support this interface.
diff --git a/src/declarative/qml/qdeclarativeparserstatus.cpp b/src/declarative/qml/qdeclarativeparserstatus.cpp
index ec6260e..978bfb4 100644
--- a/src/declarative/qml/qdeclarativeparserstatus.cpp
+++ b/src/declarative/qml/qdeclarativeparserstatus.cpp
@@ -45,8 +45,36 @@ QT_BEGIN_NAMESPACE
/*!
\class QDeclarativeParserStatus
- \since 4.7
- \brief The QDeclarativeParserStatus class provides updates on the parser state.
+ \since 4.7
+ \brief The QDeclarativeParserStatus class provides updates on the QML parser state.
+
+ QDeclarativeParserStatus provides a mechanism for classes instantiated by
+ a QDeclarativeEngine to receive notification at key points in their creation.
+
+ This class is often used for optimization purposes, as it allows you to defer an
+ expensive operation until after all the properties have been set on an
+ object. For example, QML's \l {Text} element uses the parser status
+ to defer text layout until all of its properties have been set (we
+ don't want to layout when the \c text is assigned, and then relayout
+ when the \c font is assigned, and relayout again when the \c width is assigned,
+ and so on).
+
+ To use QDeclarativeParserStatus, you must inherit both a QObject-derived class
+ and QDeclarativeParserStatus, and use the Q_INTERFACES() macro.
+
+ \code
+ class MyObject : public QObject, public QDeclarativeParserStatus
+ {
+ Q_OBJECT
+ Q_INTERFACES(QDeclarativeParserStatus)
+
+ public:
+ MyObject(QObject *parent = 0);
+ ...
+ void classBegin();
+ void componentComplete();
+ }
+ \endcode
*/
/*! \internal */
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index 6e240d8..e657dd5 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -184,6 +184,7 @@ namespace QDeclarativePrivate
int listId;
int objectSize;
void (*create)(void *);
+ QString noCreationReason;
const char *uri;
int versionMajor;
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index afd0d84..3881d0a 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QDeclarativeProperty
+\since 4.7
\brief The QDeclarativeProperty class abstracts accessing properties on objects created from QML.
As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect
diff --git a/src/declarative/qml/qdeclarativepropertyvaluesource.cpp b/src/declarative/qml/qdeclarativepropertyvaluesource.cpp
index b106d4f..a0ed78f 100644
--- a/src/declarative/qml/qdeclarativepropertyvaluesource.cpp
+++ b/src/declarative/qml/qdeclarativepropertyvaluesource.cpp
@@ -47,8 +47,10 @@ QT_BEGIN_NAMESPACE
/*!
\class QDeclarativePropertyValueSource
- \brief The QDeclarativePropertyValueSource class is inherited by property value sources such as animations and bindings.
- \internal
+ \brief The QDeclarativePropertyValueSource class is an interface for property value sources such as animations and bindings.
+
+ See \l{Property Value Sources} for information on writing custom property
+ value sources.
*/
/*!
diff --git a/src/declarative/qml/qdeclarativeproxymetaobject.cpp b/src/declarative/qml/qdeclarativeproxymetaobject.cpp
index fe0dce7..c2dce0a 100644
--- a/src/declarative/qml/qdeclarativeproxymetaobject.cpp
+++ b/src/declarative/qml/qdeclarativeproxymetaobject.cpp
@@ -41,17 +41,11 @@
#include "private/qdeclarativeproxymetaobject_p.h"
-#include <QDebug>
-
QT_BEGIN_NAMESPACE
QDeclarativeProxyMetaObject::QDeclarativeProxyMetaObject(QObject *obj, QList<ProxyData> *mList)
: metaObjects(mList), proxies(0), parent(0), object(obj)
{
-#ifdef QDECLARATIVEPROXYMETAOBJECT_DEBUG
- qWarning() << "QDeclarativeProxyMetaObject" << obj->metaObject()->className();
-#endif
-
*static_cast<QMetaObject *>(this) = *metaObjects->first().metaObject;
QObjectPrivate *op = QObjectPrivate::get(obj);
@@ -59,14 +53,6 @@ QDeclarativeProxyMetaObject::QDeclarativeProxyMetaObject(QObject *obj, QList<Pro
parent = static_cast<QAbstractDynamicMetaObject*>(op->metaObject);
op->metaObject = this;
-
-#ifdef QDECLARATIVEPROXYMETAOBJECT_DEBUG
- const QMetaObject *mo = obj->metaObject();
- while(mo) {
- qWarning() << " " << mo->className();
- mo = mo->superClass();
- }
-#endif
}
QDeclarativeProxyMetaObject::~QDeclarativeProxyMetaObject()
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index ac49332..e7c8a12 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -296,27 +296,12 @@ ProcessAST::defineObjectBinding_helper(AST::UiQualifiedId *propertyName,
if (lastTypeDot >= 0)
resolvableObjectType.replace(QLatin1Char('.'),QLatin1Char('/'));
- bool isScript = resolvableObjectType == QLatin1String("Script");
-
- if (isScript) {
- if (_stateStack.isEmpty() || _stateStack.top().property) {
- QDeclarativeError error;
- error.setDescription(QCoreApplication::translate("QDeclarativeParser","Invalid use of Script block"));
- error.setLine(typeLocation.startLine);
- error.setColumn(typeLocation.startColumn);
- _parser->_errors << error;
- return 0;
- }
- }
-
Object *obj = new Object;
- if (!isScript) {
- QDeclarativeScriptParser::TypeReference *typeRef = _parser->findOrCreateType(resolvableObjectType);
- obj->type = typeRef->id;
+ QDeclarativeScriptParser::TypeReference *typeRef = _parser->findOrCreateType(resolvableObjectType);
+ obj->type = typeRef->id;
- typeRef->refObjects.append(obj);
- }
+ typeRef->refObjects.append(obj);
// XXX this doesn't do anything (_scope never builds up)
_scope.append(resolvableObjectType);
@@ -325,11 +310,7 @@ ProcessAST::defineObjectBinding_helper(AST::UiQualifiedId *propertyName,
obj->location = location;
- if (isScript) {
-
- _stateStack.top().object->scriptBlockObjects.append(obj);
-
- } else if (propertyCount) {
+ if (propertyCount) {
Property *prop = currentProperty();
Value *v = new Value;
@@ -535,7 +516,6 @@ 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" },
{ "variant", Object::DynamicProperty::Variant, "QVariant" }
};
const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
@@ -647,11 +627,6 @@ 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;
@@ -827,62 +802,29 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
{
QDeclarativeParser::Object *obj = currentObject();
- bool isScript = (obj && obj->typeName == "Script");
-
- if (!isScript) {
-
- if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
+ if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
- Object::DynamicSlot slot;
- slot.location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
+ Object::DynamicSlot slot;
+ slot.location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
- AST::FormalParameterList *f = funDecl->formals;
- while (f) {
- slot.parameterNames << f->name->asString().toUtf8();
- f = f->finish();
- }
-
- QString body = textAt(funDecl->lbraceToken, funDecl->rbraceToken);
- slot.name = funDecl->name->asString().toUtf8();
- slot.body = body;
- obj->dynamicSlots << slot;
-
- } else {
- QDeclarativeError error;
- error.setDescription(QCoreApplication::translate("QDeclarativeParser","JavaScript declaration outside Script element"));
- error.setLine(node->firstSourceLocation().startLine);
- error.setColumn(node->firstSourceLocation().startColumn);
- _parser->_errors << error;
+ AST::FormalParameterList *f = funDecl->formals;
+ while (f) {
+ slot.parameterNames << f->name->asString().toUtf8();
+ f = f->finish();
}
- return false;
-
- } else {
- QString source;
- int line = 0;
- if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
- line = funDecl->functionToken.startLine;
- source = asString(funDecl);
- } else if (AST::VariableStatement *varStmt = AST::cast<AST::VariableStatement *>(node->sourceElement)) {
- // ignore variable declarations
- line = varStmt->declarationKindToken.startLine;
+ QString body = textAt(funDecl->lbraceToken, funDecl->rbraceToken);
+ slot.name = funDecl->name->asString().toUtf8();
+ slot.body = body;
+ obj->dynamicSlots << slot;
- QDeclarativeError error;
- error.setDescription(QCoreApplication::translate("QDeclarativeParser", "Variable declarations not allow in inline Script blocks"));
- error.setLine(node->firstSourceLocation().startLine);
- error.setColumn(node->firstSourceLocation().startColumn);
- _parser->_errors << error;
- return false;
- }
-
- Value *value = new Value;
- value->location = location(node->firstSourceLocation(),
- node->lastSourceLocation());
- value->value = QDeclarativeParser::Variant(source);
-
- obj->getDefaultProperty()->addValue(value);
+ } else {
+ QDeclarativeError error;
+ error.setDescription(QCoreApplication::translate("QDeclarativeParser","JavaScript declaration outside Script element"));
+ error.setLine(node->firstSourceLocation().startLine);
+ error.setColumn(node->firstSourceLocation().startColumn);
+ _parser->_errors << error;
}
-
return false;
}
diff --git a/src/declarative/qml/qdeclarativescriptstring.cpp b/src/declarative/qml/qdeclarativescriptstring.cpp
index 5b9afe9..8f717d1 100644
--- a/src/declarative/qml/qdeclarativescriptstring.cpp
+++ b/src/declarative/qml/qdeclarativescriptstring.cpp
@@ -55,24 +55,35 @@ public:
/*!
\class QDeclarativeScriptString
- \since 4.7
+\since 4.7
\brief The QDeclarativeScriptString class encapsulates a script and its context.
-The QDeclarativeScriptString is used by properties that want to accept a script "assignment" from QML.
+QDeclarativeScriptString is used to create QObject properties that accept a script "assignment" from QML.
-Normally, the following code would result in a binding being established for the \c script
-property. If the property had a type of QDeclarativeScriptString, the script - \e {console.log(1921)} - itself
-would be passed to the property and it could choose how to handle it.
+Normally, the following QML would result in a binding being established for the \c script
+property; i.e. \c script would be assigned the value obtained from running \c {myObj.value = Math.max(myValue, 100)}
-\code
+\qml
MyType {
- script: console.log(1921)
+ script: myObj.value = Math.max(myValue, 100)
}
+\endqml
+
+If instead the property had a type of QDeclarativeScriptString,
+the script itself -- \e {myObj.value = Math.max(myValue, 100)} -- would be passed to the \c script property
+and the class could choose how to handle it. Typically, the class will evaluate
+the script at some later time using a QDeclarativeExpression.
+
+\code
+QDeclarativeExpression expr(scriptString.context(), scriptString.script(), scriptStr.scopeObject());
+expr.value();
\endcode
+
+\sa QDeclarativeExpression
*/
/*!
-Construct an empty instance.
+Constructs an empty instance.
*/
QDeclarativeScriptString::QDeclarativeScriptString()
: d(new QDeclarativeScriptStringPrivate)
@@ -80,7 +91,7 @@ QDeclarativeScriptString::QDeclarativeScriptString()
}
/*!
-Copy \a other.
+Copies \a other.
*/
QDeclarativeScriptString::QDeclarativeScriptString(const QDeclarativeScriptString &other)
: d(other.d)
@@ -95,7 +106,7 @@ QDeclarativeScriptString::~QDeclarativeScriptString()
}
/*!
-Assign \a other to this.
+Assigns \a other to this.
*/
QDeclarativeScriptString &QDeclarativeScriptString::operator=(const QDeclarativeScriptString &other)
{
@@ -104,7 +115,7 @@ QDeclarativeScriptString &QDeclarativeScriptString::operator=(const QDeclarative
}
/*!
-Return the context for the script.
+Returns the context for the script.
*/
QDeclarativeContext *QDeclarativeScriptString::context() const
{
diff --git a/src/declarative/qml/qdeclarativetypenotavailable.cpp b/src/declarative/qml/qdeclarativetypenotavailable.cpp
new file mode 100644
index 0000000..7a84732
--- /dev/null
+++ b/src/declarative/qml/qdeclarativetypenotavailable.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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 "qdeclarativetypenotavailable_p.h"
+
+int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message)
+{
+ return qmlRegisterUncreatableType<QDeclarativeTypeNotAvailable>(uri,versionMajor,versionMinor,qmlName,message);
+}
+
+QDeclarativeTypeNotAvailable::QDeclarativeTypeNotAvailable() { }
diff --git a/src/declarative/qml/qdeclarativetypenotavailable_p.h b/src/declarative/qml/qdeclarativetypenotavailable_p.h
new file mode 100644
index 0000000..9c1c256
--- /dev/null
+++ b/src/declarative/qml/qdeclarativetypenotavailable_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 QDECLARATIVETYPENOTAVAILABLE_H
+#define QDECLARATIVETYPENOTAVAILABLE_H
+
+#include <qdeclarative.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeTypeNotAvailable : public QObject {
+ Q_OBJECT
+public:
+ QDeclarativeTypeNotAvailable();
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeTypeNotAvailable)
+
+QT_END_HEADER
+
+#endif // QDECLARATIVETYPENOTAVAILABLE_H
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index 352a6c0..c6fe161 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -55,13 +55,15 @@ int qmlRegisterValueTypeEnums(const char *qmlName)
QByteArray pointerName(name + '*');
QDeclarativePrivate::RegisterType type = {
- 0,
+ 0,
qRegisterMetaType<T *>(pointerName.constData()), 0, 0, 0,
- "Qt", 4, 6, qmlName, &T::staticMetaObject,
+ QString(),
- 0, 0,
+ "Qt", 4, 7, qmlName, &T::staticMetaObject,
+
+ 0, 0,
0, 0, 0,
@@ -712,7 +714,7 @@ int QDeclarativeFontValueType::pixelSize() const
void QDeclarativeFontValueType::setPixelSize(int size)
{
- if (size >=0) {
+ if (size >0) {
if (pointSizeSet)
qWarning() << "Both point size and pixel size set. Using pixel size.";
font.setPixelSize(size);
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index fdcbeee..57bf726 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -623,13 +623,6 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
}
break;
- case QDeclarativeInstruction::StoreScript:
- {
- QObject *target = stack.top();
- ctxt->addScript(scripts.at(instr.storeScript.value), target);
- }
- break;
-
case QDeclarativeInstruction::StoreImportedScript:
{
ctxt->addImportedScript(scripts.at(instr.storeScript.value));
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index c4d47b3..45f04a0 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -86,7 +86,6 @@ public:
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
@@ -112,6 +111,9 @@ void QDeclarativeVMEVariant::cleanup()
type == QMetaType::Bool ||
type == QMetaType::Double) {
type = QVariant::Invalid;
+ } else if (type == QMetaType::QObjectStar) {
+ ((QDeclarativeGuard<QObject>*)dataPtr())->~QDeclarativeGuard<QObject>();
+ type = QVariant::Invalid;
} else if (type == QMetaType::QString) {
((QString *)dataPtr())->~QString();
type = QVariant::Invalid;
@@ -160,7 +162,7 @@ QObject *QDeclarativeVMEVariant::asQObject()
if (type != QMetaType::QObjectStar)
setValue((QObject *)0);
- return *(QObject **)(dataPtr());
+ return *(QDeclarativeGuard<QObject> *)(dataPtr());
}
const QVariant &QDeclarativeVMEVariant::asQVariant()
@@ -256,8 +258,9 @@ void QDeclarativeVMEVariant::setValue(QObject *v)
if (type != QMetaType::QObjectStar) {
cleanup();
type = QMetaType::QObjectStar;
+ new (dataPtr()) QDeclarativeGuard<QObject>();
}
- *(QObject **)(dataPtr()) = v;
+ *(QDeclarativeGuard<QObject>*)(dataPtr()) = v;
}
void QDeclarativeVMEVariant::setValue(const QVariant &v)
@@ -465,8 +468,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (c == QMetaObject::ReadProperty) {
*reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id);
} else if (c == QMetaObject::WriteProperty) {
- needActivate = (data[id].asQVariant() != *reinterpret_cast<QVariant *>(a[0]));
- data[id].setValue(*reinterpret_cast<QVariant *>(a[0]));
+ writeVarProperty(id, *reinterpret_cast<QVariant *>(a[0]));
}
} else {
@@ -682,6 +684,8 @@ QScriptValue QDeclarativeVMEMetaObject::readVarProperty(int id)
{
if (data[id].dataType() == qMetaTypeId<QScriptValue>())
return data[id].asQScriptValue();
+ else if (data[id].dataType() == QMetaType::QObjectStar)
+ return QDeclarativeEnginePrivate::get(ctxt->engine)->objectClass->newQObject(data[id].asQObject());
else
return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueFromVariant(data[id].asQVariant());
}
@@ -690,7 +694,9 @@ QVariant QDeclarativeVMEMetaObject::readVarPropertyAsVariant(int id)
{
if (data[id].dataType() == qMetaTypeId<QScriptValue>())
return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueToVariant(data[id].asQScriptValue());
- else
+ else if (data[id].dataType() == QMetaType::QObjectStar)
+ return QVariant::fromValue(data[id].asQObject());
+ else
return data[id].asQVariant();
}
@@ -700,6 +706,15 @@ void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &val
activate(object, methodOffset + id, 0);
}
+void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QVariant &value)
+{
+ if (value.userType() == QMetaType::QObjectStar)
+ data[id].setValue(qvariant_cast<QObject *>(value));
+ else
+ data[id].setValue(value);
+ activate(object, methodOffset + id, 0);
+}
+
void QDeclarativeVMEMetaObject::listChanged(int id)
{
activate(object, methodOffset + id, 0);
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index 76390c9..4fc3269 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -148,6 +148,7 @@ private:
QScriptValue readVarProperty(int);
QVariant readVarPropertyAsVariant(int);
void writeVarProperty(int, const QScriptValue &);
+ void writeVarProperty(int, const QVariant &);
QAbstractDynamicMetaObject *parent;
diff --git a/src/declarative/qml/qdeclarativewatcher.cpp b/src/declarative/qml/qdeclarativewatcher.cpp
index 9ea84b8..842b3c4 100644
--- a/src/declarative/qml/qdeclarativewatcher.cpp
+++ b/src/declarative/qml/qdeclarativewatcher.cpp
@@ -110,7 +110,7 @@ void QDeclarativeWatchProxy::notifyValueChanged()
{
QVariant v;
if (m_expr)
- v = m_expr->value();
+ v = m_expr->evaluate();
else
v = m_property.read(m_object);
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index be2a1a7..b7e1832 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -1305,7 +1305,7 @@ void QDeclarativeXMLHttpRequest::printError(const QScriptValue& sv)
{
QDeclarativeError error;
QDeclarativeExpressionPrivate::exceptionToError(sv.engine(), error);
- qWarning().nospace() << qPrintable(error.toString());
+ QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate::get(sv.engine()), error);
}
void QDeclarativeXMLHttpRequest::destroyNetwork()
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index c48662c..3848593 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -40,6 +40,7 @@ SOURCES += \
$$PWD/qdeclarativepropertycache.cpp \
$$PWD/qdeclarativenotifier.cpp \
$$PWD/qdeclarativeintegercache.cpp \
+ $$PWD/qdeclarativetypenotavailable.cpp \
$$PWD/qdeclarativetypenamecache.cpp \
$$PWD/qdeclarativescriptstring.cpp \
$$PWD/qdeclarativeobjectscriptclass.cpp \
@@ -112,6 +113,7 @@ HEADERS += \
$$PWD/qdeclarativepropertycache_p.h \
$$PWD/qdeclarativenotifier_p.h \
$$PWD/qdeclarativeintegercache_p.h \
+ $$PWD/qdeclarativetypenotavailable_p.h \
$$PWD/qdeclarativetypenamecache_p.h \
$$PWD/qdeclarativescriptstring.h \
$$PWD/qdeclarativeobjectscriptclass_p.h \