From 85628b1798ec4c98333c8f4529f5d5628f3f1bbb Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 18 Feb 2010 13:47:38 +0100 Subject: qdoc: Added "Inherited by" list to QML elements. But the listed elements are not links yet, just plain text. Task: QTBUG-8153 --- tools/qdoc3/cppcodeparser.cpp | 13 ++++-------- tools/qdoc3/htmlgenerator.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++ tools/qdoc3/htmlgenerator.h | 1 + tools/qdoc3/node.cpp | 20 +++++++++++++++++++ tools/qdoc3/node.h | 6 +++++- 5 files changed, 76 insertions(+), 10 deletions(-) diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index c8655a4..021d64a 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -1033,7 +1033,10 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, #ifdef QDOC_QML else if (command == COMMAND_QMLINHERITS) { setLink(node, Node::InheritsLink, arg); - } + if (node->subType() == Node::QmlClass) { + QmlClassNode::addInheritedBy(arg,node->name()); + } + } else if (command == COMMAND_QMLDEFAULT) { QmlPropGroupNode* qpgn = static_cast(node); qpgn->setDefault(); @@ -2299,14 +2302,6 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake) QString imagesPath = fullPath + "/images"; QStringList imageFiles = Config::getFilesHere(imagesPath,exampleImageFilter); -#if 0 - qDebug() << "examplePath:" << examplePath; - qDebug() << " exampleFiles" << exampleFiles; - qDebug() << "imagesPath:" << imagesPath; - qDebug() << "fullPath:" << fullPath; - qDebug() << " imageFiles" << imageFiles; -#endif - if (!exampleFiles.isEmpty()) { // move main.cpp and to the end, if it exists QString mainCpp; diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index e341a03..01e79dd 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1525,6 +1525,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) generateQmlInherits(qml_cn, marker); generateQmlInstantiates(qml_cn, marker); generateBrief(qml_cn, marker); + generateQmlInheritedBy(qml_cn, marker); sections = marker->qmlSections(qml_cn,CodeMarker::Summary); s = sections.begin(); while (s != sections.end()) { @@ -4309,6 +4310,51 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn, } /*! + Output the "Inherit by" list for the QML element, + if it is inherited by any other elements. + */ +void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn, + CodeMarker* marker) +{ + if (cn) { + QStringList subs; + QmlClassNode::subclasses(cn->name(),subs); + if (!subs.isEmpty()) { + subs.sort(); + Text text; + text << Atom::ParaLeft << "Inherited by "; + for (int i = 0; i < subs.size(); ++i) { + text << subs.at(i); + text << separator(i, subs.size()); + } + text << Atom::ParaRight; + generateText(text, cn, marker); + } +#if 0 + if (cn->links().contains(Node::InheritsLink)) { + QPair linkPair; + linkPair = cn->links()[Node::InheritsLink]; + QStringList strList(linkPair.first); + const Node* n = myTree->findNode(strList,Node::Fake); + if (n && n->subType() == Node::QmlClass) { + const QmlClassNode* qcn = static_cast(n); + out() << "

"; + Text text; + text << "[Inherits "; + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, linkPair.second); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << "]"; + generateText(text, cn, marker); + out() << "

"; + } + } +#endif + } +} + +/*! Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]" line for the QML element, if there should be one. diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index 369d6c3..551bead 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -185,6 +185,7 @@ class HtmlGenerator : public PageGenerator const InnerNode *relative, CodeMarker *marker); void generateQmlInherits(const QmlClassNode* cn, CodeMarker* marker); + void generateQmlInheritedBy(const QmlClassNode* cn, CodeMarker* marker); void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker); void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker); #endif diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index ec574f8..4ddcfb1 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -1257,6 +1257,7 @@ bool TargetNode::isInnerNode() const #ifdef QDOC_QML bool QmlClassNode::qmlOnly = false; +QMultiMap QmlClassNode::inheritedBy; /*! Constructs a Qml class node (i.e. a Fake node with the @@ -1290,6 +1291,25 @@ QString QmlClassNode::fileBase() const } /*! + Record the fact that QML class \a base is inherited by + QML class \a sub. + */ +void QmlClassNode::addInheritedBy(const QString& base, const QString& sub) +{ + inheritedBy.insert(base,sub); +} + +/*! + Loads the list \a subs with the names of all the subclasses of \a base. + */ +void QmlClassNode::subclasses(const QString& base, QStringList& subs) +{ + subs.clear(); + if (inheritedBy.contains(base)) + subs = inheritedBy.values(base); +} + +/*! Constructs a Qml basic type node (i.e. a Fake node with the subtype QmlBasicType. The new node has the given \a parent and \a name. diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index 021a052..de26025 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -383,11 +383,15 @@ class QmlClassNode : public FakeNode const ClassNode* classNode() const { return cnode; } virtual QString fileBase() const; + static void addInheritedBy(const QString& base, const QString& sub); + static void subclasses(const QString& base, QStringList& subs); + public: static bool qmlOnly; + static QMultiMap inheritedBy; private: - const ClassNode* cnode; + const ClassNode* cnode; }; class QmlBasicTypeNode : public FakeNode -- cgit v0.12 From 8865e9cd3389956f2e5909a1261566f21eef128f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:15:00 +0100 Subject: Cleanup: Move exception helper functions to QScriptEnginePrivate Because that's where they belong. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine_p.h | 7 +++-- src/script/api/qscriptvalue.cpp | 60 ++++++++++++++++++++-------------------- src/script/api/qscriptvalue_p.h | 3 -- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 6780b2c..86ac5df 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -177,6 +177,9 @@ public: void agentDeleted(QScriptEngineAgent *agent); + static inline void saveException(JSC::ExecState *, JSC::JSValue *); + static inline void restoreException(JSC::ExecState *, JSC::JSValue); + void setCurrentException(QScriptValue exception) { m_currentException = exception; } QScriptValue currentException() const { return m_currentException; } void clearCurrentException() { m_currentException.d_ptr.reset(); } @@ -514,7 +517,7 @@ inline void QScriptValuePrivate::operator delete(void *ptr) qFree(d); } -inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) +inline void QScriptEnginePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) { if (exec) { *val = exec->exception(); @@ -524,7 +527,7 @@ inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValu } } -inline void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) +inline void QScriptEnginePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) { if (exec && val) exec->setException(val); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 5bfe46a..1faade9 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -910,9 +910,9 @@ QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType Q_ASSERT(pp->engine != 0); JSC::ExecState *exec = pp->engine->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return pp->engine->scriptValueFromJSCValue(result); } @@ -1103,9 +1103,9 @@ bool QScriptValue::equals(const QScriptValue &other) const if (eng_p) { JSC::ExecState *exec = eng_p->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } } @@ -1192,16 +1192,16 @@ QString QScriptValue::toString() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::UString str = d->jscValue.toString(exec); if (exec && exec->hadException() && !str.size()) { JSC::JSValue savedException2; - QScriptValuePrivate::saveException(exec, &savedException2); + QScriptEnginePrivate::saveException(exec, &savedException2); str = savedException2.toString(exec); - QScriptValuePrivate::restoreException(exec, savedException2); + QScriptEnginePrivate::restoreException(exec, savedException2); } if (savedException) - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return str; } case QScriptValuePrivate::Number: @@ -1233,9 +1233,9 @@ qsreal QScriptValue::toNumber() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); qsreal result = d->jscValue.toNumber(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1260,9 +1260,9 @@ bool QScriptValue::toBoolean() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1296,9 +1296,9 @@ bool QScriptValue::toBool() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1330,9 +1330,9 @@ qint32 QScriptValue::toInt32() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); qint32 result = d->jscValue.toInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1364,9 +1364,9 @@ quint32 QScriptValue::toUInt32() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); quint32 result = d->jscValue.toUInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1428,9 +1428,9 @@ qsreal QScriptValue::toInteger() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); qsreal result = d->jscValue.toInteger(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1490,9 +1490,9 @@ QVariant QScriptValue::toVariant() const // try to convert to primitive JSC::ExecState *exec = d->engine->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue prim = d->jscValue.toPrimitive(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); if (!prim.isObject()) return d->engine->scriptValueFromJSCValue(prim).toVariant(); } else if (isNumber()) { @@ -1882,12 +1882,12 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs); if (exec->hadException()) { result = exec->exception(); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -1963,12 +1963,12 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, } JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs); if (exec->hadException()) { result = exec->exception(); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2015,12 +2015,12 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args) JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs); if (exec->hadException()) { result = JSC::asObject(exec->exception()); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2074,13 +2074,13 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments) } JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs); if (exec->hadException()) { if (exec->exception().isObject()) result = JSC::asObject(exec->exception()); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 7440d21..76fbc18 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -109,9 +109,6 @@ public: return -1; } - static inline void saveException(JSC::ExecState*, JSC::JSValue*); - static inline void restoreException(JSC::ExecState*, JSC::JSValue); - QScriptEnginePrivate *engine; Type type; JSC::JSValue jscValue; -- cgit v0.12 From c86e7dfb0f6bcc0821ece5cf42a793d164d3f7a2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:25:50 +0100 Subject: Move some helper function declarations outside QT_NO_QOBJECT guard These are not dependent on QObject, I don't know how they ended up inside there. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine_p.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 86ac5df..9a357e5 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -184,6 +184,20 @@ public: QScriptValue currentException() const { return m_currentException; } void clearCurrentException() { m_currentException.d_ptr.reset(); } + static QScriptSyntaxCheckResult checkSyntax(const QString &program); + static bool canEvaluate(const QString &program); + + inline QScriptValuePrivate *allocateScriptValuePrivate(size_t); + inline void freeScriptValuePrivate(QScriptValuePrivate *p); + + inline void registerScriptValue(QScriptValuePrivate *value); + inline void unregisterScriptValue(QScriptValuePrivate *value); + void detachAllRegisteredScriptValues(); + + inline void registerScriptString(QScriptStringPrivate *value); + inline void unregisterScriptString(QScriptStringPrivate *value); + void detachAllRegisteredScriptStrings(); + #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, @@ -191,8 +205,6 @@ public: JSC::JSValue newQMetaObject(const QMetaObject *metaObject, JSC::JSValue ctor); - static QScriptSyntaxCheckResult checkSyntax(const QString &program); - static bool canEvaluate(const QString &program); static bool convertToNativeQObject(const QScriptValue &value, const QByteArray &targetType, void **result); @@ -223,17 +235,6 @@ public: bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver, JSC::JSValue function); - inline QScriptValuePrivate *allocateScriptValuePrivate(size_t); - inline void freeScriptValuePrivate(QScriptValuePrivate *p); - - inline void registerScriptValue(QScriptValuePrivate *value); - inline void unregisterScriptValue(QScriptValuePrivate *value); - void detachAllRegisteredScriptValues(); - - inline void registerScriptString(QScriptStringPrivate *value); - inline void unregisterScriptString(QScriptStringPrivate *value); - void detachAllRegisteredScriptStrings(); - // private slots void _q_objectDestroyed(QObject *); #endif -- cgit v0.12 From 0cad410d78758c79126d15664ec3d527883a9496 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:36:32 +0100 Subject: Cleanup: Move number conversion functions to QScriptEnginePrivate Also rename ToUint{16,32} to ToUInt{16,32} to follow the Qt naming (it takes precedence over the ECMA one). Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 72 +++++++++++++++++++++++++++++++- src/script/api/qscriptengine_p.h | 5 +++ src/script/api/qscriptvalue.cpp | 88 +++------------------------------------- 3 files changed, 81 insertions(+), 84 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 237b6fd..d8f7b3f 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -24,7 +24,6 @@ #include "config.h" #include "qscriptengine.h" #include "qscriptsyntaxchecker_p.h" -#include "qnumeric.h" #include "qscriptengine_p.h" #include "qscriptengineagent_p.h" @@ -41,6 +40,9 @@ #include #include +#include +#include + #include "Error.h" #include "JSArray.h" #include "JSLock.h" @@ -328,6 +330,74 @@ public: namespace QScript { +static const qsreal D32 = 4294967296.0; + +qint32 ToInt32(qsreal n) +{ + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + qsreal sign = (n < 0) ? -1.0 : 1.0; + qsreal abs_n = fabs(n); + + n = ::fmod(sign * ::floor(abs_n), D32); + const double D31 = D32 / 2.0; + + if (sign == -1 && n < -D31) + n += D32; + + else if (sign != -1 && n >= D31) + n -= D32; + + return qint32 (n); +} + +quint32 ToUInt32(qsreal n) +{ + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + qsreal sign = (n < 0) ? -1.0 : 1.0; + qsreal abs_n = fabs(n); + + n = ::fmod(sign * ::floor(abs_n), D32); + + if (n < 0) + n += D32; + + return quint32 (n); +} + +quint16 ToUInt16(qsreal n) +{ + static const qsreal D16 = 65536.0; + + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + qsreal sign = (n < 0) ? -1.0 : 1.0; + qsreal abs_n = fabs(n); + + n = ::fmod(sign * ::floor(abs_n), D16); + + if (n < 0) + n += D16; + + return quint16 (n); +} + +qsreal ToInteger(qsreal n) +{ + if (qIsNaN(n)) + return 0; + + if (n == 0 || qIsInf(n)) + return n; + + int sign = n < 0 ? -1 : 1; + return sign * ::floor(::fabs(n)); +} + void GlobalClientData::mark(JSC::MarkStack& markStack) { engine->mark(markStack); diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 9a357e5..f55dc27 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -83,6 +83,11 @@ namespace QScript #endif class TimeoutCheckerProxy; + qint32 ToInt32(qsreal); + quint32 ToUInt32(qsreal); + quint16 ToUInt16(qsreal); + qsreal ToInteger(qsreal); + //some conversion helper functions inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 1faade9..e8c2050 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -180,86 +180,8 @@ \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. */ -// ### move - -#include -#include - QT_BEGIN_NAMESPACE -namespace QScript -{ - -static const qsreal D32 = 4294967296.0; - -qint32 ToInt32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - const double D31 = D32 / 2.0; - - if (sign == -1 && n < -D31) - n += D32; - - else if (sign != -1 && n >= D31) - n -= D32; - - return qint32 (n); -} - -quint32 ToUint32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - - if (n < 0) - n += D32; - - return quint32 (n); -} - -quint16 ToUint16(qsreal n) -{ - static const qsreal D16 = 65536.0; - - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D16); - - if (n < 0) - n += D16; - - return quint16 (n); -} - -qsreal ToInteger(qsreal n) -{ - if (qIsNaN(n)) - return 0; - - if (n == 0 || qIsInf(n)) - return n; - - int sign = n < 0 ? -1 : 1; - return sign * ::floor(::fabs(n)); -} - -} // namespace QScript - QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const { JSC::JSValue result; @@ -1370,9 +1292,9 @@ quint32 QScriptValue::toUInt32() const return result; } case QScriptValuePrivate::Number: - return QScript::ToUint32(d->numberValue); + return QScript::ToUInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt32(((JSC::UString)d->stringValue).toDouble()); } return 0; } @@ -1397,12 +1319,12 @@ quint16 QScriptValue::toUInt16() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { // ### no equivalent function in JSC - return QScript::ToUint16(toNumber()); + return QScript::ToUInt16(toNumber()); } case QScriptValuePrivate::Number: - return QScript::ToUint16(d->numberValue); + return QScript::ToUInt16(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt16(((JSC::UString)d->stringValue).toDouble()); } return 0; } -- cgit v0.12 From d65299511f80c67be4c326a91106ae273aad6d66 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:59:48 +0100 Subject: Move implementation of QScriptValue construction functions to private class In preparation of getting rid of QScriptValue construction internally; the implementation should only call the private functions that operate directly on JSC::JSValues. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 185 ++++++++++++++++++++------------------- src/script/api/qscriptengine_p.h | 39 +++++++++ 2 files changed, 133 insertions(+), 91 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index d8f7b3f..988e362 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -44,11 +44,8 @@ #include #include "Error.h" -#include "JSArray.h" #include "JSLock.h" #include "Interpreter.h" -#include "DateConstructor.h" -#include "RegExpConstructor.h" #include "PrototypeFunction.h" #include "InitializeThreading.h" @@ -60,9 +57,7 @@ #include "Parser.h" #include "Operations.h" -#include "utils/qscriptdate_p.h" #include "bridge/qscriptfunction_p.h" -#include "bridge/qscriptobject_p.h" #include "bridge/qscriptclassobject_p.h" #include "bridge/qscriptvariant_p.h" #include "bridge/qscriptqobject_p.h" @@ -1497,6 +1492,92 @@ void QScriptEnginePrivate::detachAllRegisteredScriptStrings() registeredScriptStrings = 0; } +#ifndef QT_NO_REGEXP + +extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); + +JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) +{ + JSC::JSValue buf[2]; + JSC::ArgList args(buf, sizeof(buf)); + + //convert the pattern to a ECMAScript pattern + QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax()); + if (regexp.isMinimal()) { + QString ecmaPattern; + int len = pattern.length(); + ecmaPattern.reserve(len); + int i = 0; + const QChar *wc = pattern.unicode(); + bool inBracket = false; + while (i < len) { + QChar c = wc[i++]; + ecmaPattern += c; + switch (c.unicode()) { + case '?': + case '+': + case '*': + case '}': + if (!inBracket) + ecmaPattern += QLatin1Char('?'); + break; + case '\\': + if (i < len) + ecmaPattern += wc[i++]; + break; + case '[': + inBracket = true; + break; + case ']': + inBracket = false; + break; + default: + break; + } + } + pattern = ecmaPattern; + } + + JSC::UString jscPattern = pattern; + QString flags; + if (regexp.caseSensitivity() == Qt::CaseInsensitive) + flags.append(QLatin1Char('i')); + JSC::UString jscFlags = flags; + buf[0] = JSC::jsString(exec, jscPattern); + buf[1] = JSC::jsString(exec, jscFlags); + return JSC::constructRegExp(exec, args); +} + +#endif + +JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QString &pattern, const QString &flags) +{ + JSC::JSValue buf[2]; + JSC::ArgList args(buf, sizeof(buf)); + JSC::UString jscPattern = pattern; + QString strippedFlags; + if (flags.contains(QLatin1Char('i'))) + strippedFlags += QLatin1Char('i'); + if (flags.contains(QLatin1Char('m'))) + strippedFlags += QLatin1Char('m'); + if (flags.contains(QLatin1Char('g'))) + strippedFlags += QLatin1Char('g'); + JSC::UString jscFlags = strippedFlags; + buf[0] = JSC::jsString(exec, jscPattern); + buf[1] = JSC::jsString(exec, jscFlags); + return JSC::constructRegExp(exec, args); +} + +JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) +{ + QScriptObject *obj = new (currentFrame) QScriptObject(variantWrapperObjectStructure); + obj->setDelegate(new QScript::QVariantDelegate(value)); + JSC::JSValue proto = defaultPrototype(value.userType()); + if (proto) + obj->setPrototype(proto); + return obj; +} + #ifdef QT_NO_QOBJECT QScriptEngine::QScriptEngine() @@ -1669,56 +1750,7 @@ extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSValue buf[2]; - JSC::ArgList args(buf, sizeof(buf)); - - //convert the pattern to a ECMAScript pattern - QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax()); - if (regexp.isMinimal()) { - QString ecmaPattern; - int len = pattern.length(); - ecmaPattern.reserve(len); - int i = 0; - const QChar *wc = pattern.unicode(); - bool inBracket = false; - while (i < len) { - QChar c = wc[i++]; - ecmaPattern += c; - switch (c.unicode()) { - case '?': - case '+': - case '*': - case '}': - if (!inBracket) - ecmaPattern += QLatin1Char('?'); - break; - case '\\': - if (i < len) - ecmaPattern += wc[i++]; - break; - case '[': - inBracket = true; - break; - case ']': - inBracket = false; - break; - default: - break; - } - } - pattern = ecmaPattern; - } - - JSC::UString jscPattern = pattern; - QString flags; - if (regexp.caseSensitivity() == Qt::CaseInsensitive) - flags.append(QLatin1Char('i')); - JSC::UString jscFlags = flags; - buf[0] = JSC::jsString(exec, jscPattern); - buf[1] = JSC::jsString(exec, jscFlags); - JSC::JSObject* result = JSC::constructRegExp(exec, args); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp)); } #endif // QT_NO_REGEXP @@ -1736,14 +1768,7 @@ QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) QScriptValue QScriptEngine::newVariant(const QVariant &value) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - QScriptObject *obj = new (exec) QScriptObject(d->variantWrapperObjectStructure); - obj->setDelegate(new QScript::QVariantDelegate(value)); - QScriptValue result = d->scriptValueFromJSCValue(obj); - QScriptValue proto = defaultPrototype(value.userType()); - if (proto.isValid()) - result.setPrototype(proto); - return result; + return d->scriptValueFromJSCValue(d->newVariant(value)); } /*! @@ -1882,9 +1907,7 @@ QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, QScriptValue QScriptEngine::newObject() { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSObject *result = new (exec)QScriptObject(d->scriptObjectStructure); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newObject()); } /*! @@ -2007,9 +2030,7 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature QScriptValue QScriptEngine::newArray(uint length) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSArray* result = JSC::constructEmptyArray(exec, length); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length)); } /*! @@ -2022,22 +2043,7 @@ QScriptValue QScriptEngine::newArray(uint length) QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSValue buf[2]; - JSC::ArgList args(buf, sizeof(buf)); - JSC::UString jscPattern = pattern; - QString strippedFlags; - if (flags.contains(QLatin1Char('i'))) - strippedFlags += QLatin1Char('i'); - if (flags.contains(QLatin1Char('m'))) - strippedFlags += QLatin1Char('m'); - if (flags.contains(QLatin1Char('g'))) - strippedFlags += QLatin1Char('g'); - JSC::UString jscFlags = strippedFlags; - buf[0] = JSC::jsString(exec, jscPattern); - buf[1] = JSC::jsString(exec, jscFlags); - JSC::JSObject* result = JSC::constructRegExp(exec, args); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags)); } /*! @@ -2048,11 +2054,7 @@ QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &fla QScriptValue QScriptEngine::newDate(qsreal value) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSValue val = JSC::jsNumber(exec, value); - JSC::ArgList args(&val, 1); - JSC::JSObject *result = JSC::constructDate(exec, args); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); } /*! @@ -2062,7 +2064,8 @@ QScriptValue QScriptEngine::newDate(qsreal value) */ QScriptValue QScriptEngine::newDate(const QDateTime &value) { - return newDate(QScript::FromDateTime(value)); + Q_D(QScriptEngine); + return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); } #ifndef QT_NO_QOBJECT diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index f55dc27..46df429 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -41,10 +41,15 @@ #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" +#include "bridge/qscriptobject_p.h" +#include "utils/qscriptdate_p.h" +#include "DateConstructor.h" #include "Debugger.h" +#include "JSArray.h" #include "Lexer.h" #include "RefPtr.h" +#include "RegExpConstructor.h" #include "SourceProvider.h" #include "Structure.h" #include "JSGlobalObject.h" @@ -203,6 +208,18 @@ public: inline void unregisterScriptString(QScriptStringPrivate *value); void detachAllRegisteredScriptStrings(); + static inline JSC::JSValue newArray(JSC::ExecState *, uint length); + static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value); + static inline JSC::JSValue newDate(JSC::ExecState *, const QDateTime &); + inline JSC::JSValue newObject(); + +#ifndef QT_NO_REGEXP + static JSC::JSValue newRegExp(JSC::ExecState *, const QRegExp &); +#endif + + static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags); + JSC::JSValue newVariant(const QVariant &); + #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, @@ -587,6 +604,28 @@ inline JSC::ExecState *QScriptEnginePrivate::globalExec() const return originalGlobalObject()->globalExec(); } +inline JSC::JSValue QScriptEnginePrivate::newArray(JSC::ExecState *exec, uint length) +{ + return JSC::constructEmptyArray(exec, length); +} + +inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal value) +{ + JSC::JSValue val = JSC::jsNumber(exec, value); + JSC::ArgList args(&val, 1); + return JSC::constructDate(exec, args); +} + +inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value) +{ + return newDate(exec, QScript::FromDateTime(value)); +} + +inline JSC::JSValue QScriptEnginePrivate::newObject() +{ + return new (currentFrame)QScriptObject(scriptObjectStructure); +} + QT_END_NAMESPACE #endif -- cgit v0.12 From bc5c2c7362e0ad60990871e84426027a812937fc Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 13:10:12 +0100 Subject: Cleanup: Move value conversion code to helper functions In preparation of doing this conversion in more places. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 1 - src/script/api/qscriptengine_p.h | 50 ++++++++++++++++++++++++++++++++++++++++ src/script/api/qscriptvalue.cpp | 20 ++++++++-------- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 988e362..06233d9 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include "Error.h" diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 46df429..daf670f 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -38,6 +38,7 @@ #include "private/qobject_p.h" #include +#include #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" @@ -93,6 +94,15 @@ namespace QScript quint16 ToUInt16(qsreal); qsreal ToInteger(qsreal); + inline bool ToBool(qsreal); + inline bool ToBool(const QString &); + inline qsreal ToNumber(const QString &); + inline qint32 ToInt32(const QString &); + inline quint32 ToUInt32(const QString &); + inline quint16 ToUInt16(const QString &); + inline qsreal ToInteger(const QString &); + inline QString ToString(qsreal); + //some conversion helper functions inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); @@ -396,6 +406,46 @@ inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) return static_cast(exec->globalData().clientData)->engine; } +inline QString ToString(qsreal value) +{ + return JSC::UString::from(value); +} + +inline qsreal ToNumber(const QString &value) +{ + return ((JSC::UString)value).toDouble(); +} + +inline qint32 ToInt32(const QString &value) +{ + return ToInt32(ToNumber(value)); +} + +inline quint32 ToUInt32(const QString &value) +{ + return ToUInt32(ToNumber(value)); +} + +inline quint16 ToUInt16(const QString &value) +{ + return ToUInt16(ToNumber(value)); +} + +inline qsreal ToInteger(const QString &value) +{ + return ToInteger(ToNumber(value)); +} + +inline bool ToBool(qsreal value) +{ + return (value != 0) && !qIsNaN(value); +} + +inline bool ToBool(const QString &value) +{ + return !value.isEmpty(); +} + } // namespace QScript inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size) diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index e8c2050..724bbe3 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1127,7 +1127,7 @@ QString QScriptValue::toString() const return str; } case QScriptValuePrivate::Number: - return JSC::UString::from(d->numberValue); + return QScript::ToString(d->numberValue); case QScriptValuePrivate::String: return d->stringValue; } @@ -1163,7 +1163,7 @@ qsreal QScriptValue::toNumber() const case QScriptValuePrivate::Number: return d->numberValue; case QScriptValuePrivate::String: - return ((JSC::UString)d->stringValue).toDouble(); + return QScript::ToNumber(d->stringValue); } return 0; } @@ -1188,9 +1188,9 @@ bool QScriptValue::toBoolean() const return result; } case QScriptValuePrivate::Number: - return (d->numberValue != 0) && !qIsNaN(d->numberValue); + return QScript::ToBool(d->numberValue); case QScriptValuePrivate::String: - return (!d->stringValue.isEmpty()); + return QScript::ToBool(d->stringValue); } return false; } @@ -1224,9 +1224,9 @@ bool QScriptValue::toBool() const return result; } case QScriptValuePrivate::Number: - return (d->numberValue != 0) && !qIsNaN(d->numberValue); + return QScript::ToBool(d->numberValue); case QScriptValuePrivate::String: - return (!d->stringValue.isEmpty()); + return QScript::ToBool(d->stringValue); } return false; } @@ -1260,7 +1260,7 @@ qint32 QScriptValue::toInt32() const case QScriptValuePrivate::Number: return QScript::ToInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToInt32(d->stringValue); } return 0; } @@ -1294,7 +1294,7 @@ quint32 QScriptValue::toUInt32() const case QScriptValuePrivate::Number: return QScript::ToUInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUInt32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt32(d->stringValue); } return 0; } @@ -1324,7 +1324,7 @@ quint16 QScriptValue::toUInt16() const case QScriptValuePrivate::Number: return QScript::ToUInt16(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUInt16(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt16(d->stringValue); } return 0; } @@ -1358,7 +1358,7 @@ qsreal QScriptValue::toInteger() const case QScriptValuePrivate::Number: return QScript::ToInteger(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToInteger(d->stringValue); } return 0; } -- cgit v0.12 From af4ccb478650b7efd5de3d81439173cd31931bd2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 13:54:18 +0100 Subject: Move more script value conversion code to helper functions In preparation of operating purely on JSC::JSValue internally. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine_p.h | 131 +++++++++++++++++++++++++++++++++++++++ src/script/api/qscriptvalue.cpp | 86 +++++++------------------ 2 files changed, 152 insertions(+), 65 deletions(-) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index daf670f..5f079f4 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -37,8 +37,10 @@ #include "private/qobject_p.h" +#include #include #include +#include #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" @@ -46,11 +48,14 @@ #include "utils/qscriptdate_p.h" #include "DateConstructor.h" +#include "DateInstance.h" #include "Debugger.h" +#include "ErrorInstance.h" #include "JSArray.h" #include "Lexer.h" #include "RefPtr.h" #include "RegExpConstructor.h" +#include "RegExpObject.h" #include "SourceProvider.h" #include "Structure.h" #include "JSGlobalObject.h" @@ -134,6 +139,23 @@ public: static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; } static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; } + static inline bool isArray(JSC::JSValue); + static inline bool isDate(JSC::JSValue); + static inline bool isError(JSC::JSValue); + static inline bool isObject(JSC::JSValue); + static inline bool isRegExp(JSC::JSValue); + static inline bool isVariant(JSC::JSValue); + + static inline bool toBool(JSC::ExecState *, JSC::JSValue); + static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue); + static inline qsreal toNumber(JSC::ExecState *, JSC::JSValue); + static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue); + static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue); + static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue); + static inline QString toString(JSC::ExecState *, JSC::JSValue); + + static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue); + static bool convert(const QScriptValue &value, int type, void *ptr, QScriptEnginePrivate *eng); @@ -676,6 +698,115 @@ inline JSC::JSValue QScriptEnginePrivate::newObject() return new (currentFrame)QScriptObject(scriptObjectStructure); } +inline bool QScriptEnginePrivate::isObject(JSC::JSValue value) +{ + return value && value.isObject(); +} + +inline bool QScriptEnginePrivate::isArray(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::JSArray::info); +} + +inline bool QScriptEnginePrivate::isDate(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::DateInstance::info); +} + +inline bool QScriptEnginePrivate::isError(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::ErrorInstance::info); +} + +inline bool QScriptEnginePrivate::isRegExp(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::RegExpObject::info); +} + +inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value) +{ + if (!isObject(value) || !value.inherits(&QScriptObject::info)) + return false; + QScriptObject *object = static_cast(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); +} + +inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + bool result = value.toBoolean(exec); + restoreException(exec, savedException); + return result; +} + +inline qsreal QScriptEnginePrivate::toInteger(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + qsreal result = value.toInteger(exec); + restoreException(exec, savedException); + return result; +} + +inline qsreal QScriptEnginePrivate::toNumber(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + qsreal result = value.toNumber(exec); + restoreException(exec, savedException); + return result; +} + +inline qint32 QScriptEnginePrivate::toInt32(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + qint32 result = value.toInt32(exec); + restoreException(exec, savedException); + return result; +} + +inline quint32 QScriptEnginePrivate::toUInt32(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + quint32 result = value.toUInt32(exec); + restoreException(exec, savedException); + return result; +} + +inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue value) +{ + // ### no equivalent function in JSC + return QScript::ToUInt16(toNumber(exec, value)); +} + +inline QString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + JSC::UString str = value.toString(exec); + if (exec && exec->hadException() && !str.size()) { + JSC::JSValue savedException2; + saveException(exec, &savedException2); + str = savedException2.toString(exec); + restoreException(exec, savedException2); + } + if (savedException) + restoreException(exec, savedException); + return str; +} + +inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *, JSC::JSValue value) +{ + if (!isDate(value)) + return QDateTime(); + qsreal t = static_cast(JSC::asObject(value))->internalNumber(); + return QScript::ToDateTime(t, Qt::LocalTime); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 724bbe3..929f606 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -29,21 +29,15 @@ #include "qscriptengine_p.h" #include "qscriptstring_p.h" -#include "JSArray.h" #include "JSGlobalObject.h" #include "JSImmediate.h" #include "JSObject.h" #include "JSValue.h" #include "JSFunction.h" -#include "DateInstance.h" -#include "ErrorInstance.h" -#include "RegExpObject.h" #include "Identifier.h" #include "Operations.h" #include "Arguments.h" -#include -#include #include #include #include @@ -629,9 +623,9 @@ QScriptValue &QScriptValue::operator=(const QScriptValue &other) bool QScriptValue::isError() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::ErrorInstance::info); + return QScriptEnginePrivate::isError(d->jscValue); } /*! @@ -643,9 +637,9 @@ bool QScriptValue::isError() const bool QScriptValue::isArray() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::JSArray::info); + return QScriptEnginePrivate::isArray(d->jscValue); } /*! @@ -657,9 +651,9 @@ bool QScriptValue::isArray() const bool QScriptValue::isDate() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::DateInstance::info); + return QScriptEnginePrivate::isDate(d->jscValue); } /*! @@ -671,9 +665,9 @@ bool QScriptValue::isDate() const bool QScriptValue::isRegExp() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::RegExpObject::info); + return QScriptEnginePrivate::isRegExp(d->jscValue); } /*! @@ -1113,18 +1107,7 @@ QString QScriptValue::toString() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - JSC::UString str = d->jscValue.toString(exec); - if (exec && exec->hadException() && !str.size()) { - JSC::JSValue savedException2; - QScriptEnginePrivate::saveException(exec, &savedException2); - str = savedException2.toString(exec); - QScriptEnginePrivate::restoreException(exec, savedException2); - } - if (savedException) - QScriptEnginePrivate::restoreException(exec, savedException); - return str; + return QScriptEnginePrivate::toString(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToString(d->numberValue); @@ -1154,11 +1137,7 @@ qsreal QScriptValue::toNumber() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toNumber(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toNumber(exec, d->jscValue); } case QScriptValuePrivate::Number: return d->numberValue; @@ -1181,11 +1160,7 @@ bool QScriptValue::toBoolean() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toBool(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToBool(d->numberValue); @@ -1217,11 +1192,7 @@ bool QScriptValue::toBool() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toBool(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToBool(d->numberValue); @@ -1251,11 +1222,7 @@ qint32 QScriptValue::toInt32() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - qint32 result = d->jscValue.toInt32(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toInt32(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToInt32(d->numberValue); @@ -1285,11 +1252,7 @@ quint32 QScriptValue::toUInt32() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - quint32 result = d->jscValue.toUInt32(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toUInt32(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToUInt32(d->numberValue); @@ -1318,8 +1281,8 @@ quint16 QScriptValue::toUInt16() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - // ### no equivalent function in JSC - return QScript::ToUInt16(toNumber()); + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + return QScriptEnginePrivate::toUInt16(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToUInt16(d->numberValue); @@ -1349,11 +1312,7 @@ qsreal QScriptValue::toInteger() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toInteger(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toInteger(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToInteger(d->numberValue); @@ -1456,10 +1415,9 @@ QScriptValue QScriptValue::toObject() const QDateTime QScriptValue::toDateTime() const { Q_D(const QScriptValue); - if (!isDate()) + if (!d || !d->engine) return QDateTime(); - qsreal t = static_cast(JSC::asObject(d->jscValue))->internalNumber(); - return QScript::ToDateTime(t, Qt::LocalTime); + return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue); } #ifndef QT_NO_REGEXP @@ -2151,11 +2109,9 @@ bool QScriptValue::isObject() const bool QScriptValue::isVariant() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return false; - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return QScriptEnginePrivate::isVariant(d->jscValue); } /*! -- cgit v0.12 From 8e0a364f7baed4bbc7ff711be2a15692a40c3e93 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 14:23:42 +0100 Subject: Move property helper functions to QScriptEnginePrivate More preparation for operating purely on JSC::JSValue internally. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 166 ++++++++++++++++++++++++++++++ src/script/api/qscriptengine_p.h | 99 +++++++++++++++--- src/script/api/qscriptvalue.cpp | 211 ++++++--------------------------------- src/script/api/qscriptvalue_p.h | 18 ++-- 4 files changed, 288 insertions(+), 206 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 06233d9..a045bab 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1577,6 +1577,172 @@ JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) return obj; } +JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) +{ + JSC::JSValue result; + if (!(resolveMode & QScriptValue::ResolvePrototype)) { + // Look in the object's own properties + JSC::JSObject *object = JSC::asObject(value); + JSC::PropertySlot slot(object); + if (object->getOwnPropertySlot(exec, id, slot)) + result = slot.getValue(exec, id); + } + if (!result && (resolveMode & QScriptValue::ResolveScope)) { + // ### check if it's a function object and look in the scope chain + JSC::JSValue scope = property(exec, value, QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); + if (isObject(scope)) + result = property(exec, scope, id, resolveMode); + } + return result; +} + +JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode) +{ + JSC::JSValue result; + if (!(resolveMode & QScriptValue::ResolvePrototype)) { + // Look in the object's own properties + JSC::JSObject *object = JSC::asObject(value); + JSC::PropertySlot slot(object); + if (object->getOwnPropertySlot(exec, index, slot)) + result = slot.getValue(exec, index); + } + return result; +} + +void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::Identifier &id, + JSC::JSValue value, const QScriptValue::PropertyFlags &flags) +{ + JSC::JSObject *thisObject = JSC::asObject(objectValue); + JSC::JSValue setter = thisObject->lookupSetter(exec, id); + JSC::JSValue getter = thisObject->lookupGetter(exec, id); + if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { + if (!value) { + // deleting getter/setter + if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { + // deleting both: just delete the property + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + } else if (flags & QScriptValue::PropertyGetter) { + // preserve setter, if there is one + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + if (setter && setter.isObject()) + thisObject->defineSetter(exec, id, JSC::asObject(setter)); + } else { // flags & QScriptValue::PropertySetter + // preserve getter, if there is one + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + if (getter && getter.isObject()) + thisObject->defineGetter(exec, id, JSC::asObject(getter)); + } + } else { + if (value.isObject()) { // ### should check if it has callData() + // defining getter/setter + if (id == exec->propertyNames().underscoreProto) { + qWarning("QScriptValue::setProperty() failed: " + "cannot set getter or setter of native property `__proto__'"); + } else { + if (flags & QScriptValue::PropertyGetter) + thisObject->defineGetter(exec, id, JSC::asObject(value)); + if (flags & QScriptValue::PropertySetter) + thisObject->defineSetter(exec, id, JSC::asObject(value)); + } + } else { + qWarning("QScriptValue::setProperty(): getter/setter must be a function"); + } + } + } else { + // setting the value + if (getter && getter.isObject() && !(setter && setter.isObject())) { + qWarning("QScriptValue::setProperty() failed: " + "property '%s' has a getter but no setter", + qPrintable(QString(id.ustring()))); + return; + } + if (!value) { + // ### check if it's a getter/setter property + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + } else if (flags != QScriptValue::KeepExistingFlags) { + if (thisObject->hasOwnProperty(exec, id)) + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? + unsigned attribs = 0; + if (flags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (flags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (flags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + attribs |= flags & QScriptValue::UserRange; + thisObject->putWithAttributes(exec, id, value, attribs); + } else { + JSC::PutPropertySlot slot; + thisObject->put(exec, id, value, slot); + } + } +} + +void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, quint32 index, + JSC::JSValue value, const QScriptValue::PropertyFlags &flags) +{ + if (!value) { + JSC::asObject(objectValue)->deleteProperty(exec, index, /*checkDontDelete=*/false); + } else { + if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { + // fall back to string-based setProperty(), since there is no + // JSC::JSObject::defineGetter(unsigned) + setProperty(exec, objectValue, JSC::Identifier::from(exec, index), value, flags); + } else { + if (flags != QScriptValue::KeepExistingFlags) { + // if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) + // JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); + unsigned attribs = 0; + if (flags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (flags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (flags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + attribs |= flags & QScriptValue::UserRange; + JSC::asObject(objectValue)->putWithAttributes(exec, index, value, attribs); + } else { + JSC::asObject(objectValue)->put(exec, index, value); + } + } + } +} + +QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, + const QScriptValue::ResolveFlags &mode) +{ + JSC::JSObject *object = JSC::asObject(value); + unsigned attribs = 0; + JSC::PropertyDescriptor descriptor; + if (object->getOwnPropertyDescriptor(exec, id, descriptor)) + attribs = descriptor.attributes(); + else if (!object->getPropertyAttributes(exec, id, attribs)) { + if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { + JSC::JSValue proto = object->prototype(); + return propertyFlags(exec, proto, id, mode); + } + return 0; + } + QScriptValue::PropertyFlags result = 0; + if (attribs & JSC::ReadOnly) + result |= QScriptValue::ReadOnly; + if (attribs & JSC::DontEnum) + result |= QScriptValue::SkipInEnumeration; + if (attribs & JSC::DontDelete) + result |= QScriptValue::Undeletable; + //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) + if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) + result |= QScriptValue::PropertyGetter; + if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) + result |= QScriptValue::PropertySetter; +#ifndef QT_NO_QOBJECT + if (attribs & QScript::QObjectMemberAttribute) + result |= QScriptValue::QObjectMember; +#endif + result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); + return result; +} + #ifdef QT_NO_QOBJECT QScriptEngine::QScriptEngine() diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 5f079f4..4be9146 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -156,6 +156,24 @@ public: static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue); + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, + int resolveMode = QScriptValue::ResolvePrototype); + static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode); + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index, + int resolveMode = QScriptValue::ResolvePrototype); + static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode); + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const QString &, int resolveMode); + static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const QString &name, JSC::JSValue, + const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); + static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue, + const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); + static void setProperty(JSC::ExecState*, JSC::JSValue object, quint32 index, JSC::JSValue, + const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); + static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, + const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode); + static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, + const QString &name, const QScriptValue::ResolveFlags &mode); + static bool convert(const QScriptValue &value, int type, void *ptr, QScriptEnginePrivate *eng); @@ -568,32 +586,83 @@ inline void QScriptValuePrivate::initFrom(const QString &value) engine->registerScriptValue(this); } -inline QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode) const +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const QString &name, int resolveMode) { - JSC::ExecState *exec = engine->currentFrame; - return property(JSC::Identifier(exec, name), resolveMode); + return property(exec, value, JSC::Identifier(exec, name), resolveMode); } -inline QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) { - Q_ASSERT(isObject()); - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); + Q_ASSERT(isObject(value)); + JSC::JSObject *object = JSC::asObject(value); JSC::PropertySlot slot(object); if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot)) - return engine->scriptValueFromJSCValue(slot.getValue(exec, id)); - return propertyHelper(id, resolveMode); + return slot.getValue(exec, id); + return propertyHelper(exec, value, id, resolveMode); } -inline QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode) { - Q_ASSERT(isObject()); - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); + Q_ASSERT(isObject(value)); + JSC::JSObject *object = JSC::asObject(value); JSC::PropertySlot slot(object); if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot)) - return engine->scriptValueFromJSCValue(slot.getValue(exec, index)); - return propertyHelper(index, resolveMode); + return slot.getValue(exec, index); + return propertyHelper(exec, value, index, resolveMode); +} + +inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, + const QString &name, + const QScriptValue::ResolveFlags &mode) +{ + return propertyFlags(exec, value, JSC::Identifier(exec, name), mode); +} + +inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const QString &name, + JSC::JSValue value, const QScriptValue::PropertyFlags &flags) +{ + setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags); +} + +inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +{ + return QScriptEnginePrivate::property(engine->currentFrame, jscValue, id, resolveMode); +} + +inline JSC::JSValue QScriptValuePrivate::property(quint32 index, int resolveMode) const +{ + return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode); +} + +inline JSC::JSValue QScriptValuePrivate::property(const QString &name, int resolveMode) const +{ + JSC::ExecState *exec = engine->currentFrame; + return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode); +} + +inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags( + const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const +{ + return QScriptEnginePrivate::propertyFlags(engine->currentFrame, jscValue, id, mode); +} + +inline void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags) +{ + QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, id, value, flags); +} + +inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags) +{ + QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, index, value, flags); +} + +inline void QScriptValuePrivate::setProperty(const QString &name, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags) +{ + JSC::ExecState *exec = engine->currentFrame; + QScriptEnginePrivate::setProperty(exec, jscValue, JSC::Identifier(exec, name), value, flags); } inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine) diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 929f606..a7d9f79 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -176,152 +176,6 @@ QT_BEGIN_NAMESPACE -QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const -{ - JSC::JSValue result; - if (!(resolveMode & QScriptValue::ResolvePrototype)) { - // Look in the object's own properties - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(object); - if (object->getOwnPropertySlot(exec, id, slot)) - result = slot.getValue(exec, id); - } - if (!result && (resolveMode & QScriptValue::ResolveScope)) { - // ### check if it's a function object and look in the scope chain - QScriptValue scope = property(QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); - if (scope.isObject()) - result = engine->scriptValueToJSCValue(QScriptValuePrivate::get(scope)->property(id, resolveMode)); - } - return engine->scriptValueFromJSCValue(result); -} - -QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const -{ - JSC::JSValue result; - if (!(resolveMode & QScriptValue::ResolvePrototype)) { - // Look in the object's own properties - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(object); - if (object->getOwnPropertySlot(exec, index, slot)) - result = slot.getValue(exec, index); - } - return engine->scriptValueFromJSCValue(result); -} - -void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value, - const QScriptValue::PropertyFlags &flags) -{ - QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); - if (valueEngine && (valueEngine != engine)) { - qWarning("QScriptValue::setProperty(%s) failed: " - "cannot set value created in a different engine", - qPrintable(QString(id.ustring()))); - return; - } - JSC::ExecState *exec = engine->currentFrame; - JSC::JSValue jsValue = engine->scriptValueToJSCValue(value); - JSC::JSObject *thisObject = JSC::asObject(jscValue); - JSC::JSValue setter = thisObject->lookupSetter(exec, id); - JSC::JSValue getter = thisObject->lookupGetter(exec, id); - if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { - if (!jsValue) { - // deleting getter/setter - if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { - // deleting both: just delete the property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - } else if (flags & QScriptValue::PropertyGetter) { - // preserve setter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - if (setter && setter.isObject()) - thisObject->defineSetter(exec, id, JSC::asObject(setter)); - } else { // flags & QScriptValue::PropertySetter - // preserve getter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - if (getter && getter.isObject()) - thisObject->defineGetter(exec, id, JSC::asObject(getter)); - } - } else { - if (jsValue.isObject()) { // ### should check if it has callData() - // defining getter/setter - if (id == exec->propertyNames().underscoreProto) { - qWarning("QScriptValue::setProperty() failed: " - "cannot set getter or setter of native property `__proto__'"); - } else { - if (flags & QScriptValue::PropertyGetter) - thisObject->defineGetter(exec, id, JSC::asObject(jsValue)); - if (flags & QScriptValue::PropertySetter) - thisObject->defineSetter(exec, id, JSC::asObject(jsValue)); - } - } else { - qWarning("QScriptValue::setProperty(): getter/setter must be a function"); - } - } - } else { - // setting the value - if (getter && getter.isObject() && !(setter && setter.isObject())) { - qWarning("QScriptValue::setProperty() failed: " - "property '%s' has a getter but no setter", - qPrintable(QString(id.ustring()))); - return; - } - if (!jsValue) { - // ### check if it's a getter/setter property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - } else if (flags != QScriptValue::KeepExistingFlags) { - if (thisObject->hasOwnProperty(exec, id)) - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - thisObject->putWithAttributes(exec, id, jsValue, attribs); - } else { - JSC::PutPropertySlot slot; - thisObject->put(exec, id, jsValue, slot); - } - } -} - -QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id, - const QScriptValue::ResolveFlags &mode) const -{ - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - unsigned attribs = 0; - JSC::PropertyDescriptor descriptor; - if (object->getOwnPropertyDescriptor(exec, id, descriptor)) - attribs = descriptor.attributes(); - else if (!object->getPropertyAttributes(exec, id, attribs)) { - if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { - QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype()); - return QScriptValuePrivate::get(proto)->propertyFlags(id, mode); - } - return 0; - } - QScriptValue::PropertyFlags result = 0; - if (attribs & JSC::ReadOnly) - result |= QScriptValue::ReadOnly; - if (attribs & JSC::DontEnum) - result |= QScriptValue::SkipInEnumeration; - if (attribs & JSC::DontDelete) - result |= QScriptValue::Undeletable; - //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) - if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) - result |= QScriptValue::PropertyGetter; - if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) - result |= QScriptValue::PropertySetter; - if (attribs & QScript::QObjectMemberAttribute) - result |= QScriptValue::QObjectMember; - result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); - return result; -} - QVariant &QScriptValuePrivate::variantValue() const { Q_ASSERT(jscValue.inherits(&QScriptObject::info)); @@ -732,7 +586,8 @@ QScriptValue QScriptValue::scope() const if (!d || !d->isObject()) return QScriptValue(); // ### make hidden property - return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); + JSC::JSValue result = d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); + return d->engine->scriptValueFromJSCValue(result); } /*! @@ -1433,9 +1288,9 @@ QRegExp QScriptValue::toRegExp() const Q_D(const QScriptValue); if (!isRegExp()) return QRegExp(); - QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); + QString pattern = property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) + if (property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) kase = Qt::CaseInsensitive; return QRegExp(pattern, kase, QRegExp::RegExp2); } @@ -1514,8 +1369,15 @@ void QScriptValue::setProperty(const QString &name, const QScriptValue &value, Q_D(QScriptValue); if (!d || !d->isObject()) return; - JSC::ExecState *exec = d->engine->currentFrame; - d->setProperty(JSC::Identifier(exec, name), value, flags); + QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); + if (valueEngine && (valueEngine != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name)); + return; + } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(name, jsValue, flags); } /*! @@ -1539,7 +1401,7 @@ QScriptValue QScriptValue::property(const QString &name, Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); - return d->property(name, mode); + return d->engine->scriptValueFromJSCValue(d->property(name, mode)); } /*! @@ -1561,7 +1423,7 @@ QScriptValue QScriptValue::property(quint32 arrayIndex, Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); - return d->property(arrayIndex, mode); + return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode)); } /*! @@ -1588,33 +1450,8 @@ void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value, "cannot set value created in a different engine"); return; } - JSC::ExecState *exec = d->engine->currentFrame; - JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value); - if (!jscValue) { - JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex, /*checkDontDelete=*/false); - } else { - if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { - // fall back to string-based setProperty(), since there is no - // JSC::JSObject::defineGetter(unsigned) - d->setProperty(JSC::Identifier::from(exec, arrayIndex), value, flags); - } else { - if (flags != QScriptValue::KeepExistingFlags) { -// if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) -// JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - JSC::asObject(d->jscValue)->putWithAttributes(exec, arrayIndex, jscValue, attribs); - } else { - JSC::asObject(d->jscValue)->put(exec, arrayIndex, jscValue); - } - } - } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(arrayIndex, jsValue, flags); } /*! @@ -1635,7 +1472,7 @@ QScriptValue QScriptValue::property(const QScriptString &name, Q_D(const QScriptValue); if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return QScriptValue(); - return d->property(name.d_ptr->identifier, mode); + return d->engine->scriptValueFromJSCValue(d->property(name.d_ptr->identifier, mode)); } /*! @@ -1658,7 +1495,15 @@ void QScriptValue::setProperty(const QScriptString &name, Q_D(QScriptValue); if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return; - d->setProperty(name.d_ptr->identifier, value, flags); + QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); + if (valueEngine && (valueEngine != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name.toString())); + return; + } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(name.d_ptr->identifier, jsValue, flags); } /*! @@ -2177,7 +2022,7 @@ QScriptValue QScriptValue::data() const return d->engine->scriptValueFromJSCValue(scriptObject->data()); } else { // ### make hidden property - return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); + return property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); } } diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 76fbc18..dedc250 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -89,14 +89,16 @@ public: return q.d_ptr->engine; } - inline QScriptValue property(const JSC::Identifier &id, int resolveMode) const; - QScriptValue propertyHelper(const JSC::Identifier &id, int resolveMode) const; - inline QScriptValue property(quint32 index, int resolveMode) const; - QScriptValue propertyHelper(quint32, int resolveMode) const; - inline QScriptValue property(const QString &, int resolveMode) const; - void setProperty(const JSC::Identifier &id, const QScriptValue &value, - const QScriptValue::PropertyFlags &flags); - QScriptValue::PropertyFlags propertyFlags( + inline JSC::JSValue property(const JSC::Identifier &id, int resolveMode) const; + inline JSC::JSValue property(quint32 index, int resolveMode) const; + inline JSC::JSValue property(const QString &, int resolveMode) const; + inline void setProperty(const QString &name, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags); + inline void setProperty(const JSC::Identifier &id, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags); + inline void setProperty(quint32 index, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags); + inline QScriptValue::PropertyFlags propertyFlags( const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const; void detachFromEngine(); -- cgit v0.12 From d5af42b1b7d792188c689d5425493756f2dcb79e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 15:29:32 +0100 Subject: Avoid calling out to public API in the QtScript implementation There's no reason to construct QScriptValues when JSC::JSValues can be operated on directly. A benchmark showed that ~10% of the time for reading a QObject property from a script was spent just creating and destroying QScriptValue temporaries. It's time to finally get rid of this potential bottleneck, not just in the QObject integration but everywhere. This change refactors the code so that all internal operations are performed on JSC::JSValue (most importantly, conversion from/to Qt types), and the public API functions are just thin wrappers around these. E.g. instead of doing enginePrivate->scriptValueFromJSCValue(jsValue).toQObject() the implementation now does QScriptEnginePrivate::toQObject(jsValue) Other operations are delegated to the engine implementation in similar style. Task-number: QTBUG-8304 Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 487 ++++++++++++++++---------- src/script/api/qscriptengine_p.h | 150 +++++++- src/script/api/qscriptvalue.cpp | 106 +----- src/script/api/qscriptvalue_p.h | 3 - src/script/bridge/qscriptclassobject.cpp | 2 +- src/script/bridge/qscriptdeclarativeclass.cpp | 16 +- src/script/bridge/qscriptqobject.cpp | 106 +++--- src/script/bridge/qscriptvariant.cpp | 2 +- 8 files changed, 513 insertions(+), 359 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index a045bab..739b3fc 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -54,6 +54,7 @@ #include "TimeoutChecker.h" #include "JSFunction.h" #include "Parser.h" +#include "PropertyNameArray.h" #include "Operations.h" #include "bridge/qscriptfunction_p.h" @@ -546,11 +547,9 @@ JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObjec if (isFunction(arg1)) slot = arg1; else { - // ### don't go via QScriptValue QScript::SaveFrameHelper saveFrame(engine, exec); - QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); - QString propertyName(arg1.toString(exec)); - slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); + QString propertyName(QScriptEnginePrivate::toString(exec, arg1)); + slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype); } } @@ -630,11 +629,9 @@ JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject * if (isFunction(arg1)) slot = arg1; else { - // ### don't go via QScriptValue QScript::SaveFrameHelper saveFrame(engine, exec); - QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); - QString propertyName = arg1.toString(exec); - slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); + QString propertyName = QScriptEnginePrivate::toString(exec, arg1); + slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype); } } @@ -908,22 +905,15 @@ QScriptEnginePrivate::~QScriptEnginePrivate() } } -QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v) -{ - QScriptValue result = create(v.userType(), v.data()); - Q_ASSERT(result.isValid()); - return result; -} - -QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, int targetType) +QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType) { QVariant v(targetType, (void *)0); - if (QScriptEnginePrivate::convert(value, targetType, v.data(), this)) + if (convertValue(exec, value, targetType, v.data())) return v; if (uint(targetType) == QVariant::LastType) - return value.toVariant(); - if (value.isVariant()) { - v = value.toVariant(); + return toVariant(exec, value); + if (isVariant(value)) { + v = variantValue(value); if (v.canConvert(QVariant::Type(targetType))) { v.convert(QVariant::Type(targetType)); return v; @@ -934,88 +924,61 @@ QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, i return QVariant(targetType, *reinterpret_cast(v.data())); } } - return QVariant(); } -JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v) -{ - // ### it's inefficient to convert to QScriptValue and then to JSValue - QScriptValue vv = scriptValueFromVariant(v); - QScriptValuePrivate *p = QScriptValuePrivate::get(vv); - switch (p->type) { - case QScriptValuePrivate::JavaScriptCore: - return p->jscValue; - case QScriptValuePrivate::Number: - return JSC::jsNumber(currentFrame, p->numberValue); - case QScriptValuePrivate::String: { - JSC::UString str = p->stringValue; - return JSC::jsString(currentFrame, str); - } - } - return JSC::JSValue(); -} - -QVariant QScriptEnginePrivate::jscValueToVariant(JSC::JSValue value, int targetType) +JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst) { - // ### it's inefficient to convert to QScriptValue and then to QVariant - return scriptValueToVariant(scriptValueFromJSCValue(value), targetType); -} - -QScriptValue QScriptEnginePrivate::arrayFromStringList(const QStringList &lst) -{ - Q_Q(QScriptEngine); - QScriptValue arr = q->newArray(lst.size()); + JSC::JSValue arr = newArray(exec, lst.size()); for (int i = 0; i < lst.size(); ++i) - arr.setProperty(i, QScriptValue(q, lst.at(i))); + setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i))); return arr; } -QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr) +QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr) { QStringList lst; - uint len = arr.property(QLatin1String("length")).toUInt32(); + uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); for (uint i = 0; i < len; ++i) - lst.append(arr.property(i).toString()); + lst.append(toString(exec, property(exec, arr, i))); return lst; } -QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst) +JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst) { - Q_Q(QScriptEngine); - QScriptValue arr = q->newArray(lst.size()); + JSC::JSValue arr = newArray(exec, lst.size()); for (int i = 0; i < lst.size(); ++i) - arr.setProperty(i, scriptValueFromVariant(lst.at(i))); + setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i))); return arr; } -QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr) +QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr) { QVariantList lst; - uint len = arr.property(QLatin1String("length")).toUInt32(); + uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); for (uint i = 0; i < len; ++i) - lst.append(arr.property(i).toVariant()); + lst.append(toVariant(exec, property(exec, arr, i))); return lst; } -QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap) +JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap) { - Q_Q(QScriptEngine); - QScriptValue obj = q->newObject(); + JSC::JSValue obj = JSC::constructEmptyObject(exec); QVariantMap::const_iterator it; for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) - obj.setProperty(it.key(), scriptValueFromVariant(it.value())); + setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value())); return obj; } -QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj) +QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj) { + JSC::PropertyNameArray propertyNames(exec); + propertyNames.setShouldCache(false); + JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, /*includeNonEnumerable=*/true); QVariantMap vmap; - QScriptValueIterator it(obj); - while (it.hasNext()) { - it.next(); - vmap.insert(it.name(), it.value().toVariant()); - } + JSC::PropertyNameArray::const_iterator it = propertyNames.begin(); + for( ; it != propertyNames.end(); ++it) + vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it))); return vmap; } @@ -1344,13 +1307,13 @@ JSC::JSValue QScriptEnginePrivate::newQMetaObject( return result; } -bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValue &value, +bool QScriptEnginePrivate::convertToNativeQObject(JSC::ExecState *exec, JSC::JSValue value, const QByteArray &targetType, void **result) { if (!targetType.endsWith('*')) return false; - if (QObject *qobject = value.toQObject()) { + if (QObject *qobject = toQObject(exec, value)) { int start = targetType.startsWith("const ") ? 6 : 0; QByteArray className = targetType.mid(start, targetType.size()-start-1); if (void *instance = qobject->qt_metacast(className)) { @@ -1577,6 +1540,76 @@ JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) return obj; } +JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue, + const QVariant &value) +{ + if (!isObject(objectValue)) + return newVariant(value); + JSC::JSObject *jscObject = JSC::asObject(objectValue); + if (!jscObject->inherits(&QScriptObject::info)) { + qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); + return JSC::JSValue(); + } + QScriptObject *jscScriptObject = static_cast(jscObject); + if (!isVariant(objectValue)) { + jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); + } else { + setVariantValue(objectValue, value); + } + return objectValue; +} + +#ifndef QT_NO_REGEXP + +QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value) +{ + if (!isRegExp(value)) + return QRegExp(); + QString pattern = toString(exec, property(exec, value, QLatin1String("source"), QScriptValue::ResolvePrototype)); + Qt::CaseSensitivity kase = Qt::CaseSensitive; + if (toBool(exec, property(exec, value, QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype))) + kase = Qt::CaseInsensitive; + return QRegExp(pattern, kase, QRegExp::RegExp2); +} + +#endif + +QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value) +{ + if (isObject(value)) { + if (isVariant(value)) + return variantValue(value); +#ifndef QT_NO_QOBJECT + else if (isQObject(value)) + return qVariantFromValue(toQObject(exec, value)); +#endif + else if (isDate(value)) + return QVariant(toDateTime(exec, value)); +#ifndef QT_NO_REGEXP + else if (isRegExp(value)) + return QVariant(toRegExp(exec, value)); +#endif + else if (isArray(value)) + return variantListFromArray(exec, value); + else if (QScriptDeclarativeClass *dc = declarativeClass(value)) + return dc->toVariant(declarativeObject(value)); + // try to convert to primitive + JSC::JSValue savedException; + saveException(exec, &savedException); + JSC::JSValue prim = value.toPrimitive(exec); + restoreException(exec, savedException); + if (!prim.isObject()) + return toVariant(exec, prim); + } else if (value.isNumber()) { + return QVariant(toNumber(exec, value)); + } else if (value.isString()) { + return QVariant(toString(exec, value)); + } else if (value.isBoolean()) { + return QVariant(toBool(exec, value)); + } + return QVariant(); +} + JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) { JSC::JSValue result; @@ -1963,20 +1996,9 @@ QScriptValue QScriptEngine::newVariant(const QVariant &value) QScriptValue QScriptEngine::newVariant(const QScriptValue &object, const QVariant &value) { - if (!object.isObject()) - return newVariant(value); - JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(object)->jscValue); - if (!jscObject->inherits(&QScriptObject::info)) { - qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); - return QScriptValue(); - } - QScriptObject *jscScriptObject = static_cast(jscObject); - if (!object.isVariant()) { - jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); - } else { - QScriptValuePrivate::get(object)->setVariantValue(value); - } - return object; + Q_D(QScriptEngine); + JSC::JSValue jsObject = d->scriptValueToJSCValue(object); + return d->scriptValueFromJSCValue(d->newVariant(jsObject, value)); } #ifndef QT_NO_QOBJECT @@ -2789,128 +2811,126 @@ void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prot QScriptValue QScriptEngine::create(int type, const void *ptr) { Q_D(QScriptEngine); - return d->create(type, ptr); + return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr)); } -QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) +JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr) { - Q_Q(QScriptEngine); Q_ASSERT(ptr != 0); - QScriptValue result; - QScriptTypeInfo *info = m_typeInfos.value(type); + JSC::JSValue result; + QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0; + QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0; if (info && info->marshal) { - result = info->marshal(q, ptr); + result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr)); } else { // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::Void: - return QScriptValue(q, QScriptValue::UndefinedValue); + return JSC::jsUndefined(); case QMetaType::Bool: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsBoolean(*reinterpret_cast(ptr)); case QMetaType::Int: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::UInt: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::LongLong: - return QScriptValue(q, qsreal(*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal(*reinterpret_cast(ptr))); case QMetaType::ULongLong: #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.") - return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast(ptr))); #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast(ptr))); #else - return QScriptValue(q, qsreal(*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal(*reinterpret_cast(ptr))); #endif case QMetaType::Double: - return QScriptValue(q, qsreal(*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal(*reinterpret_cast(ptr))); case QMetaType::QString: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsString(exec, *reinterpret_cast(ptr)); case QMetaType::Float: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::Short: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::UShort: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::Char: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::UChar: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::QChar: - return QScriptValue(q, (*reinterpret_cast(ptr)).unicode()); + return JSC::jsNumber(exec, (*reinterpret_cast(ptr)).unicode()); case QMetaType::QStringList: - result = arrayFromStringList(*reinterpret_cast(ptr)); + result = arrayFromStringList(exec, *reinterpret_cast(ptr)); break; case QMetaType::QVariantList: - result = arrayFromVariantList(*reinterpret_cast(ptr)); + result = arrayFromVariantList(exec, *reinterpret_cast(ptr)); break; case QMetaType::QVariantMap: - result = objectFromVariantMap(*reinterpret_cast(ptr)); + result = objectFromVariantMap(exec, *reinterpret_cast(ptr)); break; case QMetaType::QDateTime: - result = q->newDate(*reinterpret_cast(ptr)); + result = newDate(exec, *reinterpret_cast(ptr)); break; case QMetaType::QDate: - result = q->newDate(QDateTime(*reinterpret_cast(ptr))); + result = newDate(exec, QDateTime(*reinterpret_cast(ptr))); break; #ifndef QT_NO_REGEXP case QMetaType::QRegExp: - result = q->newRegExp(*reinterpret_cast(ptr)); + result = newRegExp(exec, *reinterpret_cast(ptr)); break; #endif #ifndef QT_NO_QOBJECT case QMetaType::QObjectStar: case QMetaType::QWidgetStar: - result = q->newQObject(*reinterpret_cast(ptr)); + result = eng->newQObject(*reinterpret_cast(ptr)); break; #endif default: if (type == qMetaTypeId()) { - result = *reinterpret_cast(ptr); - if (!result.isValid()) - return QScriptValue(q, QScriptValue::UndefinedValue); + result = eng->scriptValueToJSCValue(*reinterpret_cast(ptr)); + if (!result) + return JSC::jsUndefined(); } #ifndef QT_NO_QOBJECT // lazy registration of some common list types else if (type == qMetaTypeId()) { - qScriptRegisterSequenceMetaType(q); - return create(type, ptr); + qScriptRegisterSequenceMetaType(eng->q_func()); + return create(exec, type, ptr); } #endif else if (type == qMetaTypeId >()) { - qScriptRegisterSequenceMetaType >(q); - return create(type, ptr); + qScriptRegisterSequenceMetaType >(eng->q_func()); + return create(exec, type, ptr); } else { QByteArray typeName = QMetaType::typeName(type); if (typeName == "QVariant") - result = scriptValueFromVariant(*reinterpret_cast(ptr)); + result = jscValueFromVariant(exec, *reinterpret_cast(ptr)); if (typeName.endsWith('*') && !*reinterpret_cast(ptr)) - return QScriptValue(q, QScriptValue::NullValue); + return JSC::jsNull(); else - result = q->newVariant(QVariant(type, ptr)); + result = eng->newVariant(QVariant(type, ptr)); } } } - if (result.isObject() && info && info->prototype - && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) { - result.setPrototype(scriptValueFromJSCValue(info->prototype)); + if (result && result.isObject() && info && info->prototype + && JSC::JSValue::strictEqual(JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) { + JSC::asObject(result)->setPrototype(info->prototype); } return result; } -bool QScriptEnginePrivate::convert(const QScriptValue &value, - int type, void *ptr, - QScriptEnginePrivate *eng) +bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value, + int type, void *ptr) { - if (!eng) - eng = QScriptValuePrivate::getEngine(value); + QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0; if (eng) { QScriptTypeInfo *info = eng->m_typeInfos.value(type); if (info && info->demarshal) { - info->demarshal(value, ptr); + info->demarshal(eng->scriptValueFromJSCValue(value), ptr); return true; } } @@ -2918,78 +2938,78 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::Bool: - *reinterpret_cast(ptr) = value.toBoolean(); + *reinterpret_cast(ptr) = toBool(exec, value); return true; case QMetaType::Int: - *reinterpret_cast(ptr) = value.toInt32(); + *reinterpret_cast(ptr) = toInt32(exec, value); return true; case QMetaType::UInt: - *reinterpret_cast(ptr) = value.toUInt32(); + *reinterpret_cast(ptr) = toUInt32(exec, value); return true; case QMetaType::LongLong: - *reinterpret_cast(ptr) = qlonglong(value.toInteger()); + *reinterpret_cast(ptr) = qlonglong(toInteger(exec, value)); return true; case QMetaType::ULongLong: - *reinterpret_cast(ptr) = qulonglong(value.toInteger()); + *reinterpret_cast(ptr) = qulonglong(toInteger(exec, value)); return true; case QMetaType::Double: - *reinterpret_cast(ptr) = value.toNumber(); + *reinterpret_cast(ptr) = toNumber(exec, value); return true; case QMetaType::QString: if (value.isUndefined() || value.isNull()) *reinterpret_cast(ptr) = QString(); else - *reinterpret_cast(ptr) = value.toString(); + *reinterpret_cast(ptr) = toString(exec, value); return true; case QMetaType::Float: - *reinterpret_cast(ptr) = value.toNumber(); + *reinterpret_cast(ptr) = toNumber(exec, value); return true; case QMetaType::Short: - *reinterpret_cast(ptr) = short(value.toInt32()); + *reinterpret_cast(ptr) = short(toInt32(exec, value)); return true; case QMetaType::UShort: - *reinterpret_cast(ptr) = value.toUInt16(); + *reinterpret_cast(ptr) = QScript::ToUInt16(toNumber(exec, value)); return true; case QMetaType::Char: - *reinterpret_cast(ptr) = char(value.toInt32()); + *reinterpret_cast(ptr) = char(toInt32(exec, value)); return true; case QMetaType::UChar: - *reinterpret_cast(ptr) = (unsigned char)(value.toInt32()); + *reinterpret_cast(ptr) = (unsigned char)(toInt32(exec, value)); return true; case QMetaType::QChar: if (value.isString()) { - QString str = value.toString(); + QString str = toString(exec, value); *reinterpret_cast(ptr) = str.isEmpty() ? QChar() : str.at(0); } else { - *reinterpret_cast(ptr) = QChar(value.toUInt16()); + *reinterpret_cast(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value))); } return true; case QMetaType::QDateTime: - if (value.isDate()) { - *reinterpret_cast(ptr) = value.toDateTime(); + if (isDate(value)) { + *reinterpret_cast(ptr) = toDateTime(exec, value); return true; } break; case QMetaType::QDate: - if (value.isDate()) { - *reinterpret_cast(ptr) = value.toDateTime().date(); + if (isDate(value)) { + *reinterpret_cast(ptr) = toDateTime(exec, value).date(); return true; } break; #ifndef QT_NO_REGEXP case QMetaType::QRegExp: - if (value.isRegExp()) { - *reinterpret_cast(ptr) = value.toRegExp(); + if (isRegExp(value)) { + *reinterpret_cast(ptr) = toRegExp(exec, value); return true; } break; #endif #ifndef QT_NO_QOBJECT case QMetaType::QObjectStar: - if (value.isQObject() || value.isNull()) { - *reinterpret_cast(ptr) = value.toQObject(); + if (isQObject(value) || value.isNull()) { + *reinterpret_cast(ptr) = toQObject(exec, value); return true; } break; case QMetaType::QWidgetStar: - if (value.isQObject() || value.isNull()) { - QObject *qo = value.toQObject(); + if (isQObject(value) || value.isNull()) { + QObject *qo = toQObject(exec, value); if (!qo || qo->isWidgetType()) { *reinterpret_cast(ptr) = reinterpret_cast(qo); return true; @@ -2997,18 +3017,18 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, } break; #endif case QMetaType::QStringList: - if (value.isArray()) { - *reinterpret_cast(ptr) = stringListFromArray(value); + if (isArray(value)) { + *reinterpret_cast(ptr) = stringListFromArray(exec, value); return true; } break; case QMetaType::QVariantList: - if (value.isArray()) { - *reinterpret_cast(ptr) = variantListFromArray(value); + if (isArray(value)) { + *reinterpret_cast(ptr) = variantListFromArray(exec, value); return true; } break; case QMetaType::QVariantMap: - if (value.isObject()) { - *reinterpret_cast(ptr) = variantMapFromObject(value); + if (isObject(value)) { + *reinterpret_cast(ptr) = variantMapFromObject(exec, value); return true; } break; default: @@ -3017,28 +3037,28 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, QByteArray name = QMetaType::typeName(type); #ifndef QT_NO_QOBJECT - if (convertToNativeQObject(value, name, reinterpret_cast(ptr))) + if (convertToNativeQObject(exec, value, name, reinterpret_cast(ptr))) return true; #endif - if (value.isVariant() && name.endsWith('*')) { + if (isVariant(value) && name.endsWith('*')) { int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = QScriptValuePrivate::get(value)->variantValue(); + QVariant &var = variantValue(value); if (valueType == var.userType()) { *reinterpret_cast(ptr) = var.data(); return true; } else { // look in the prototype chain - QScriptValue proto = value.prototype(); + JSC::JSValue proto = JSC::asObject(value)->prototype(); while (proto.isObject()) { bool canCast = false; - if (proto.isVariant()) { - canCast = (type == proto.toVariant().userType()) - || (valueType && (valueType == proto.toVariant().userType())); + if (isVariant(proto)) { + canCast = (type == variantValue(proto).userType()) + || (valueType && (valueType == variantValue(proto).userType())); } #ifndef QT_NO_QOBJECT - else if (proto.isQObject()) { + else if (isQObject(proto)) { QByteArray className = name.left(name.size()-1); - if (QObject *qobject = proto.toQObject()) + if (QObject *qobject = toQObject(exec, proto)) canCast = qobject->qt_metacast(className) != 0; } #endif @@ -3050,7 +3070,7 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, *reinterpret_cast(ptr) = var.data(); return true; } - proto = proto.prototype(); + proto = JSC::asObject(proto)->prototype(); } } } else if (value.isNull() && name.endsWith('*')) { @@ -3059,10 +3079,10 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, } else if (type == qMetaTypeId()) { if (!eng) return false; - *reinterpret_cast(ptr) = value; + *reinterpret_cast(ptr) = eng->scriptValueFromJSCValue(value); return true; } else if (name == "QVariant") { - *reinterpret_cast(ptr) = value.toVariant(); + *reinterpret_cast(ptr) = toVariant(exec, value); return true; } @@ -3072,14 +3092,14 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, if (!eng) return false; qScriptRegisterSequenceMetaType(eng->q_func()); - return convert(value, type, ptr, eng); + return convertValue(exec, value, type, ptr); } #endif else if (type == qMetaTypeId >()) { if (!eng) return false; qScriptRegisterSequenceMetaType >(eng->q_func()); - return convert(value, type, ptr, eng); + return convertValue(exec, value, type, ptr); } #if 0 @@ -3091,6 +3111,102 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, return false; } +bool QScriptEnginePrivate::convertNumber(qsreal value, int type, void *ptr) +{ + switch (QMetaType::Type(type)) { + case QMetaType::Bool: + *reinterpret_cast(ptr) = QScript::ToBool(value); + return true; + case QMetaType::Int: + *reinterpret_cast(ptr) = QScript::ToInt32(value); + return true; + case QMetaType::UInt: + *reinterpret_cast(ptr) = QScript::ToUInt32(value); + return true; + case QMetaType::LongLong: + *reinterpret_cast(ptr) = qlonglong(QScript::ToInteger(value)); + return true; + case QMetaType::ULongLong: + *reinterpret_cast(ptr) = qulonglong(QScript::ToInteger(value)); + return true; + case QMetaType::Double: + *reinterpret_cast(ptr) = value; + return true; + case QMetaType::QString: + *reinterpret_cast(ptr) = QScript::ToString(value); + return true; + case QMetaType::Float: + *reinterpret_cast(ptr) = value; + return true; + case QMetaType::Short: + *reinterpret_cast(ptr) = short(QScript::ToInt32(value)); + return true; + case QMetaType::UShort: + *reinterpret_cast(ptr) = QScript::ToUInt16(value); + return true; + case QMetaType::Char: + *reinterpret_cast(ptr) = char(QScript::ToInt32(value)); + return true; + case QMetaType::UChar: + *reinterpret_cast(ptr) = (unsigned char)(QScript::ToInt32(value)); + return true; + case QMetaType::QChar: + *reinterpret_cast(ptr) = QChar(QScript::ToUInt16(value)); + return true; + default: + break; + } + return false; +} + +bool QScriptEnginePrivate::convertString(const QString &value, int type, void *ptr) +{ + switch (QMetaType::Type(type)) { + case QMetaType::Bool: + *reinterpret_cast(ptr) = QScript::ToBool(value); + return true; + case QMetaType::Int: + *reinterpret_cast(ptr) = QScript::ToInt32(value); + return true; + case QMetaType::UInt: + *reinterpret_cast(ptr) = QScript::ToUInt32(value); + return true; + case QMetaType::LongLong: + *reinterpret_cast(ptr) = qlonglong(QScript::ToInteger(value)); + return true; + case QMetaType::ULongLong: + *reinterpret_cast(ptr) = qulonglong(QScript::ToInteger(value)); + return true; + case QMetaType::Double: + *reinterpret_cast(ptr) = QScript::ToNumber(value); + return true; + case QMetaType::QString: + *reinterpret_cast(ptr) = value; + return true; + case QMetaType::Float: + *reinterpret_cast(ptr) = QScript::ToNumber(value); + return true; + case QMetaType::Short: + *reinterpret_cast(ptr) = short(QScript::ToInt32(value)); + return true; + case QMetaType::UShort: + *reinterpret_cast(ptr) = QScript::ToUInt16(value); + return true; + case QMetaType::Char: + *reinterpret_cast(ptr) = char(QScript::ToInt32(value)); + return true; + case QMetaType::UChar: + *reinterpret_cast(ptr) = (unsigned char)(QScript::ToInt32(value)); + return true; + case QMetaType::QChar: + *reinterpret_cast(ptr) = QChar(QScript::ToUInt16(value)); + return true; + default: + break; + } + return false; +} + bool QScriptEnginePrivate::hasDemarshalFunction(int type) const { QScriptTypeInfo *info = m_typeInfos.value(type); @@ -3103,7 +3219,7 @@ bool QScriptEnginePrivate::hasDemarshalFunction(int type) const bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) { Q_D(QScriptEngine); - return QScriptEnginePrivate::convert(value, type, ptr, d); + return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr); } /*! @@ -3111,7 +3227,20 @@ bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) */ bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr) { - return QScriptEnginePrivate::convert(value, type, ptr, /*engine=*/0); + QScriptValuePrivate *vp = QScriptValuePrivate::get(value); + if (vp) { + switch (vp->type) { + case QScriptValuePrivate::JavaScriptCore: { + JSC::ExecState *exec = vp->engine ? vp->engine->currentFrame : 0; + return QScriptEnginePrivate::convertValue(exec, vp->jscValue, type, ptr); + } + case QScriptValuePrivate::Number: + return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr); + case QScriptValuePrivate::String: + return QScriptEnginePrivate::convertString(vp->stringValue, type, ptr); + } + } + return false; } /*! diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 4be9146..eff34af 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -44,7 +44,12 @@ #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" +#include "bridge/qscriptclassobject_p.h" +#include "bridge/qscriptdeclarativeclass_p.h" +#include "bridge/qscriptdeclarativeobject_p.h" #include "bridge/qscriptobject_p.h" +#include "bridge/qscriptqobject_p.h" +#include "bridge/qscriptvariant_p.h" #include "utils/qscriptdate_p.h" #include "DateConstructor.h" @@ -145,6 +150,8 @@ public: static inline bool isObject(JSC::JSValue); static inline bool isRegExp(JSC::JSValue); static inline bool isVariant(JSC::JSValue); + static inline bool isQObject(JSC::JSValue); + static inline bool isQMetaObject(JSC::JSValue); static inline bool toBool(JSC::ExecState *, JSC::JSValue); static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue); @@ -155,6 +162,12 @@ public: static inline QString toString(JSC::ExecState *, JSC::JSValue); static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue); +#ifndef QT_NO_REGEXP + static QRegExp toRegExp(JSC::ExecState*, JSC::JSValue); +#endif + static QVariant toVariant(JSC::ExecState *, JSC::JSValue); + static inline QObject *toQObject(JSC::ExecState *, JSC::JSValue); + static inline const QMetaObject *toQMetaObject(JSC::ExecState *, JSC::JSValue); static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode = QScriptValue::ResolvePrototype); @@ -174,29 +187,29 @@ public: static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, const QString &name, const QScriptValue::ResolveFlags &mode); - static bool convert(const QScriptValue &value, - int type, void *ptr, - QScriptEnginePrivate *eng); - QScriptValue create(int type, const void *ptr); + static bool convertValue(JSC::ExecState*, JSC::JSValue value, + int type, void *ptr); + static bool convertNumber(qsreal, int type, void *ptr); + static bool convertString(const QString &, int type, void *ptr); + static JSC::JSValue create(JSC::ExecState*, int type, const void *ptr); bool hasDemarshalFunction(int type) const; inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value); inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value); - QScriptValue scriptValueFromVariant(const QVariant &value); - QVariant scriptValueToVariant(const QScriptValue &value, int targetType); - - JSC::JSValue jscValueFromVariant(const QVariant &value); - QVariant jscValueToVariant(JSC::JSValue value, int targetType); + static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value); + static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType); + static inline QVariant &variantValue(JSC::JSValue value); + static inline void setVariantValue(JSC::JSValue objectValue, const QVariant &value); - QScriptValue arrayFromStringList(const QStringList &lst); - static QStringList stringListFromArray(const QScriptValue &arr); + static JSC::JSValue arrayFromStringList(JSC::ExecState*, const QStringList &lst); + static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr); - QScriptValue arrayFromVariantList(const QVariantList &lst); - static QVariantList variantListFromArray(const QScriptValue &arr); + static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst); + static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSValue arr); - QScriptValue objectFromVariantMap(const QVariantMap &vmap); - static QVariantMap variantMapFromObject(const QScriptValue &obj); + static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap); + static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSValue obj); JSC::JSValue defaultPrototype(int metaTypeId) const; void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype); @@ -269,6 +282,10 @@ public: static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags); JSC::JSValue newVariant(const QVariant &); + JSC::JSValue newVariant(JSC::JSValue objectValue, const QVariant &); + + static inline QScriptDeclarativeClass *declarativeClass(JSC::JSValue); + static inline QScriptDeclarativeClass::Object *declarativeObject(JSC::JSValue); #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, @@ -277,7 +294,7 @@ public: JSC::JSValue newQMetaObject(const QMetaObject *metaObject, JSC::JSValue ctor); - static bool convertToNativeQObject(const QScriptValue &value, + static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue, const QByteArray &targetType, void **result); @@ -525,6 +542,13 @@ inline void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *val value->next = 0; } +inline JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(JSC::ExecState *exec, const QVariant &v) +{ + JSC::JSValue result = create(exec, v.userType(), v.data()); + Q_ASSERT(result); + return result; +} + inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value) { if (!value) @@ -801,6 +825,30 @@ inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value) return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); } +inline bool QScriptEnginePrivate::isQObject(JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + if (!isObject(value) || !value.inherits(&QScriptObject::info)) + return false; + QScriptObject *object = static_cast(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || + (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && + static_cast(delegate)->scriptClass()->isQObject()))); +#else + return false; +#endif +} + +inline bool QScriptEnginePrivate::isQMetaObject(JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + return JSC::asObject(value)->inherits(&QScript::QMetaObjectWrapperObject::info); +#else + return false; +#endif +} + inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value) { JSC::JSValue savedException; @@ -876,6 +924,76 @@ inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *, JSC::JSValue return QScript::ToDateTime(t, Qt::LocalTime); } +inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + if (isObject(value) && value.inherits(&QScriptObject::info)) { + QScriptObject *object = static_cast(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + if (!delegate) + return 0; + if (delegate->type() == QScriptObjectDelegate::QtObject) + return static_cast(delegate)->value(); + if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) + return static_cast(delegate)->scriptClass()->toQObject(declarativeObject(value)); + if (delegate->type() == QScriptObjectDelegate::Variant) { + QVariant var = variantValue(value); + int type = var.userType(); + if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) + return *reinterpret_cast(var.constData()); + } + } +#endif + return 0; +} + +inline const QMetaObject *QScriptEnginePrivate::toQMetaObject(JSC::ExecState*, JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + if (isQMetaObject(value)) + return static_cast(JSC::asObject(value))->value(); +#endif + return 0; +} + +inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value) +{ + Q_ASSERT(value.inherits(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast(JSC::asObject(value))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return static_cast(delegate)->value(); +} + +inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value) +{ + Q_ASSERT(objectValue.inherits(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast(JSC::asObject(objectValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + static_cast(delegate)->setValue(value); +} + +inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v) +{ + if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast(JSC::asObject(v)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return 0; + return static_cast(delegate)->scriptClass(); +} + +inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v) +{ + if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast(JSC::asObject(v)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return 0; + return static_cast(delegate)->object(); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index a7d9f79..7f1fdaa 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -42,14 +42,6 @@ #include #include -#include "utils/qscriptdate_p.h" -#include "bridge/qscriptobject_p.h" -#include "bridge/qscriptclassobject_p.h" -#include "bridge/qscriptvariant_p.h" -#include "bridge/qscriptqobject_p.h" -#include "bridge/qscriptdeclarativeclass_p.h" -#include "bridge/qscriptdeclarativeobject_p.h" - /*! \since 4.3 \class QScriptValue @@ -176,22 +168,6 @@ QT_BEGIN_NAMESPACE -QVariant &QScriptValuePrivate::variantValue() const -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - return static_cast(delegate)->value(); -} - -void QScriptValuePrivate::setVariantValue(const QVariant &value) -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - static_cast(delegate)->setValue(value); -} - void QScriptValuePrivate::detachFromEngine() { if (isJSC()) @@ -1205,40 +1181,10 @@ QVariant QScriptValue::toVariant() const if (!d) return QVariant(); switch (d->type) { - case QScriptValuePrivate::JavaScriptCore: - if (isObject()) { - if (isVariant()) - return d->variantValue(); -#ifndef QT_NO_QOBJECT - else if (isQObject()) - return qVariantFromValue(toQObject()); -#endif - else if (isDate()) - return QVariant(toDateTime()); -#ifndef QT_NO_REGEXP - else if (isRegExp()) - return QVariant(toRegExp()); -#endif - else if (isArray()) - return QScriptEnginePrivate::variantListFromArray(*this); - else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this)) - return dc->toVariant(QScriptDeclarativeClass::object(*this)); - // try to convert to primitive - JSC::ExecState *exec = d->engine->currentFrame; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - JSC::JSValue prim = d->jscValue.toPrimitive(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - if (!prim.isObject()) - return d->engine->scriptValueFromJSCValue(prim).toVariant(); - } else if (isNumber()) { - return QVariant(toNumber()); - } else if (isString()) { - return QVariant(toString()); - } else if (isBool()) { - return QVariant(toBool()); - } - return QVariant(); + case QScriptValuePrivate::JavaScriptCore: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + return QScriptEnginePrivate::toVariant(exec, d->jscValue); + } case QScriptValuePrivate::Number: return QVariant(d->numberValue); case QScriptValuePrivate::String: @@ -1286,13 +1232,9 @@ QDateTime QScriptValue::toDateTime() const QRegExp QScriptValue::toRegExp() const { Q_D(const QScriptValue); - if (!isRegExp()) - return QRegExp(); - QString pattern = property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); - Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) - kase = Qt::CaseInsensitive; - return QRegExp(pattern, kase, QRegExp::RegExp2); + if (!d || !d->engine) + return QRegExp(); + return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue); } #endif // QT_NO_REGEXP @@ -1309,19 +1251,9 @@ QRegExp QScriptValue::toRegExp() const QObject *QScriptValue::toQObject() const { Q_D(const QScriptValue); - if (isQObject()) { - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) - return static_cast(delegate)->scriptClass()->toQObject(QScriptDeclarativeClass::object(*this)); - return static_cast(delegate)->value(); - } else if (isVariant()) { - QVariant var = toVariant(); - int type = var.userType(); - if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) - return *reinterpret_cast(var.constData()); - } - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1333,9 +1265,9 @@ QObject *QScriptValue::toQObject() const const QMetaObject *QScriptValue::toQMetaObject() const { Q_D(const QScriptValue); - if (isQMetaObject()) - return static_cast(JSC::asObject(d->jscValue))->value(); - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1971,13 +1903,9 @@ bool QScriptValue::isVariant() const bool QScriptValue::isQObject() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return false; - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || - (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && - static_cast(delegate)->scriptClass()->isQObject()))); + return QScriptEnginePrivate::isQObject(d->jscValue); } /*! @@ -1989,9 +1917,9 @@ bool QScriptValue::isQObject() const bool QScriptValue::isQMetaObject() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return JSC::asObject(d->jscValue)->inherits(&QScript::QMetaObjectWrapperObject::info); + return QScriptEnginePrivate::isQMetaObject(d->jscValue); } /*! diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index dedc250..77b7330 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -69,9 +69,6 @@ public: inline bool isJSC() const; inline bool isObject() const; - QVariant &variantValue() const; - void setVariantValue(const QVariant &value); - static inline QScriptValuePrivate *get(const QScriptValue &q) { return q.d_ptr.data(); diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index a3dd239..ce0a08e 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -206,7 +206,7 @@ JSC::JSValue JSC_HOST_CALL ClassObjectDelegate::call(JSC::ExecState *exec, JSC:: QVariant result = scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)); eng_p->popContext(); eng_p->currentFrame = oldFrame; - return eng_p->jscValueFromVariant(result); + return QScriptEnginePrivate::jscValueFromVariant(exec, result); } JSC::ConstructType ClassObjectDelegate::getConstructData(QScriptObject*, JSC::ConstructData &constructData) diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index ce2fc23..1d11ede 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -207,25 +207,17 @@ QScriptDeclarativeClass::newObjectValue(QScriptEngine *engine, QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v) { QScriptValuePrivate *d = QScriptValuePrivate::get(v); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return 0; - QScriptObject *scriptObject = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) - return 0; - return static_cast(delegate)->scriptClass(); + return QScriptEnginePrivate::declarativeClass(d->jscValue); } QScriptDeclarativeClass::Object *QScriptDeclarativeClass::object(const QScriptValue &v) { QScriptValuePrivate *d = QScriptValuePrivate::get(v); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) - return 0; - QScriptObject *scriptObject = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + if (!d || !d->isJSC()) return 0; - return static_cast(delegate)->object(); + return QScriptEnginePrivate::declarativeObject(d->jscValue); } QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Identifier &name) diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index db312bc..30e5a26 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -169,17 +169,15 @@ static inline QByteArray methodName(const QMetaMethod &method) return signature.left(signature.indexOf('(')); } -static QVariant variantFromValue(QScriptEnginePrivate *eng, - int targetType, const QScriptValue &value) +static QVariant variantFromValue(JSC::ExecState *exec, int targetType, JSC::JSValue value) { QVariant v(targetType, (void *)0); - Q_ASSERT(eng); - if (QScriptEnginePrivate::convert(value, targetType, v.data(), eng)) + if (QScriptEnginePrivate::convertValue(exec, value, targetType, v.data())) return v; if (uint(targetType) == QVariant::LastType) - return value.toVariant(); - if (value.isVariant()) { - v = value.toVariant(); + return QScriptEnginePrivate::toVariant(exec, value); + if (QScriptEnginePrivate::isVariant(value)) { + v = QScriptEnginePrivate::variantValue(value); if (v.canConvert(QVariant::Type(targetType))) { v.convert(QVariant::Type(targetType)); return v; @@ -591,38 +589,38 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c bool converted = true; int matchDistance = 0; for (int i = 0; converted && i < mtd.argumentCount(); ++i) { - QScriptValue actual; + JSC::JSValue actual; if (i < (int)scriptArgs.size()) - actual = engine->scriptValueFromJSCValue(scriptArgs.at(i)); + actual = scriptArgs.at(i); else - actual = QScriptValue(QScriptValue::UndefinedValue); + actual = JSC::jsUndefined(); QScriptMetaType argType = mtd.argumentType(i); int tid = -1; QVariant v; if (argType.isUnresolved()) { v = QVariant(QMetaType::QObjectStar, (void *)0); - converted = engine->convertToNativeQObject( - actual, argType.name(), reinterpret_cast(v.data())); + converted = QScriptEnginePrivate::convertToNativeQObject( + exec, actual, argType.name(), reinterpret_cast(v.data())); } else if (argType.isVariant()) { - if (actual.isVariant()) { - v = actual.toVariant(); + if (QScriptEnginePrivate::isVariant(actual)) { + v = QScriptEnginePrivate::variantValue(actual); } else { - v = actual.toVariant(); + v = QScriptEnginePrivate::toVariant(exec, actual); converted = v.isValid() || actual.isUndefined() || actual.isNull(); } } else { tid = argType.typeId(); v = QVariant(tid, (void *)0); - converted = QScriptEnginePrivate::convert(actual, tid, v.data(), engine); + converted = QScriptEnginePrivate::convertValue(exec, actual, tid, v.data()); if (exec->hadException()) return exec->exception(); } if (!converted) { - if (actual.isVariant()) { + if (QScriptEnginePrivate::isVariant(actual)) { if (tid == -1) tid = argType.typeId(); - QVariant vv = actual.toVariant(); + QVariant vv = QScriptEnginePrivate::variantValue(actual); if (vv.canConvert(QVariant::Type(tid))) { v = vv; converted = v.convert(QVariant::Type(tid)); @@ -649,14 +647,14 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c } if (m.isValid()) { if (actual.isNumber()) { - int ival = actual.toInt32(); + int ival = QScriptEnginePrivate::toInt32(exec, actual); if (m.valueToKey(ival) != 0) { qVariantSetValue(v, ival); converted = true; matchDistance += 10; } } else { - QString sval = actual.toString(); + QString sval = QScriptEnginePrivate::toString(exec, actual); int ival = m.keyToValue(sval.toLatin1()); if (ival != -1) { qVariantSetValue(v, ival); @@ -718,7 +716,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isDate()) { + } else if (QScriptEnginePrivate::isDate(actual)) { switch (tid) { case QMetaType::QDateTime: // perfect @@ -733,7 +731,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isRegExp()) { + } else if (QScriptEnginePrivate::isRegExp(actual)) { switch (tid) { case QMetaType::QRegExp: // perfect @@ -742,14 +740,14 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isVariant()) { + } else if (QScriptEnginePrivate::isVariant(actual)) { if (argType.isVariant() - || (actual.toVariant().userType() == tid)) { + || (QScriptEnginePrivate::toVariant(exec, actual).userType() == tid)) { // perfect } else { matchDistance += 10; } - } else if (actual.isArray()) { + } else if (QScriptEnginePrivate::isArray(actual)) { switch (tid) { case QMetaType::QStringList: case QMetaType::QVariantList: @@ -759,7 +757,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isQObject()) { + } else if (QScriptEnginePrivate::isQObject(actual)) { switch (tid) { case QMetaType::QObjectStar: case QMetaType::QWidgetStar: @@ -953,13 +951,11 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c } else { QScriptMetaType retType = chosenMethod.returnType(); if (retType.isVariant()) { - result = engine->jscValueFromVariant(*(QVariant *)params[0]); + result = QScriptEnginePrivate::jscValueFromVariant(exec, *(QVariant *)params[0]); } else if (retType.typeId() != 0) { - result = engine->scriptValueToJSCValue(engine->create(retType.typeId(), params[0])); - if (!result) { - QScriptValue sv = QScriptEnginePrivate::get(engine)->newVariant(QVariant(retType.typeId(), params[0])); - result = engine->scriptValueToJSCValue(sv); - } + result = QScriptEnginePrivate::create(exec, retType.typeId(), params[0]); + if (!result) + result = engine->newVariant(QVariant(retType.typeId(), params[0])); } else { result = JSC::jsUndefined(); } @@ -1065,15 +1061,13 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, { JSC::JSValue result = JSC::jsUndefined(); - // ### don't go via QScriptValue QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - QScriptValue object = engine->scriptValueFromJSCValue(thisValue); - QObject *qobject = object.toQObject(); + QObject *qobject = QScriptEnginePrivate::toQObject(exec, thisValue); while ((!qobject || (qobject->metaObject() != data->meta)) - && object.prototype().isObject()) { - object = object.prototype(); - qobject = object.toQObject(); + && JSC::asObject(thisValue)->prototype().isObject()) { + thisValue = JSC::asObject(thisValue)->prototype(); + qobject = QScriptEnginePrivate::toQObject(exec, thisValue); } Q_ASSERT_X(qobject, Q_FUNC_INFO, "this-object must be a QObject"); @@ -1094,7 +1088,7 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, if (scriptable) QScriptablePrivate::get(scriptable)->engine = oldEngine; - result = engine->jscValueFromVariant(v); + result = QScriptEnginePrivate::jscValueFromVariant(exec, v); } } else { // set @@ -1106,9 +1100,7 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, // string to enum value v = (QString)arg.toString(exec); } else { - // ### don't go via QScriptValue - QScriptValue tmp = engine->scriptValueFromJSCValue(arg); - v = variantFromValue(engine, prop.userType(), tmp); + v = variantFromValue(exec, prop.userType(), arg); } QScriptable *scriptable = scriptableFromQObject(qobject); @@ -1237,7 +1229,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * if (!prop.isValid()) val = JSC::jsUndefined(); else - val = eng->jscValueFromVariant(prop.read(qobject)); + val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject)); slot.setValue(val); } return true; @@ -1247,7 +1239,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * index = qobject->dynamicPropertyNames().indexOf(name); if (index != -1) { - JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name)); + JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name)); slot.setValue(val); return true; } @@ -1274,8 +1266,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * QObject *child = children.at(index); if (child->objectName() == QString(propertyName.ustring())) { QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - QScriptValue tmp = QScriptEnginePrivate::get(eng)->newQObject(child, QScriptEngine::QtOwnership, opt); - slot.setValue(eng->scriptValueToJSCValue(tmp)); + slot.setValue(eng->newQObject(child, QScriptEngine::QtOwnership, opt)); return true; } } @@ -1370,7 +1361,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS if (!prop.isValid()) val = JSC::jsUndefined(); else - val = eng->jscValueFromVariant(prop.read(qobject)); + val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject)); descriptor.setDescriptor(val, attributes); } return true; @@ -1380,7 +1371,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS index = qobject->dynamicPropertyNames().indexOf(name); if (index != -1) { - JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name)); + JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name)); descriptor.setDescriptor(val, QObjectMemberAttribute); return true; } @@ -1410,8 +1401,8 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS QObject *child = children.at(index); if (child->objectName() == QString(propertyName.ustring())) { QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - QScriptValue tmp = QScriptEnginePrivate::get(eng)->newQObject(child, QScriptEngine::QtOwnership, opt); - descriptor.setDescriptor(eng->scriptValueToJSCValue(tmp), JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum); + descriptor.setDescriptor(eng->newQObject(child, QScriptEngine::QtOwnership, opt), + JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum); return true; } } @@ -1490,7 +1481,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, // string to enum value v = (QString)value.toString(exec); } else { - v = eng->jscValueToVariant(value, prop.userType()); + v = QScriptEnginePrivate::jscValueToVariant(exec, value, prop.userType()); } (void)prop.write(qobject, v); } @@ -1512,7 +1503,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, index = qobject->dynamicPropertyNames().indexOf(name); if ((index != -1) || (opt & QScriptEngine::AutoCreateDynamicProperties)) { - QVariant v = eng->scriptValueFromJSCValue(value).toVariant(); + QVariant v = QScriptEnginePrivate::toVariant(exec, value); (void)qobject->setProperty(name, v); return; } @@ -2178,24 +2169,23 @@ void QObjectConnectionManager::execute(int slotIndex, void **argv) JSC::ExecState *exec = engine->currentFrame; QVarLengthArray argsVector(argc); for (int i = 0; i < argc; ++i) { - // ### optimize -- no need to convert via QScriptValue - QScriptValue actual; + JSC::JSValue actual; void *arg = argv[i + 1]; QByteArray typeName = parameterTypes.at(i); int argType = QMetaType::type(parameterTypes.at(i)); if (!argType) { if (typeName == "QVariant") { - actual = engine->scriptValueFromVariant(*reinterpret_cast(arg)); + actual = QScriptEnginePrivate::jscValueFromVariant(exec, *reinterpret_cast(arg)); } else { qWarning("QScriptEngine: Unable to handle unregistered datatype '%s' " "when invoking handler of signal %s::%s", typeName.constData(), meta->className(), method.signature()); - actual = QScriptValue(QScriptValue::UndefinedValue); + actual = JSC::jsUndefined(); } } else { - actual = engine->create(argType, arg); + actual = QScriptEnginePrivate::create(exec, argType, arg); } - argsVector[i] = engine->scriptValueToJSCValue(actual); + argsVector[i] = actual; } JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); diff --git a/src/script/bridge/qscriptvariant.cpp b/src/script/bridge/qscriptvariant.cpp index 0287d24..b4f0365 100644 --- a/src/script/bridge/qscriptvariant.cpp +++ b/src/script/bridge/qscriptvariant.cpp @@ -133,7 +133,7 @@ static JSC::JSValue JSC_HOST_CALL variantProtoFuncToString(JSC::ExecState *exec, bool QVariantDelegate::compareToObject(QScriptObject *, JSC::ExecState *exec, JSC::JSObject *o2) { const QVariant &variant1 = value(); - return variant1 == scriptEngineFromExec(exec)->scriptValueFromJSCValue(o2).toVariant(); + return variant1 == QScriptEnginePrivate::toVariant(exec, o2); } QVariantPrototype::QVariantPrototype(JSC::ExecState* exec, WTF::PassRefPtr structure, -- cgit v0.12 From 83d7242271cf8196a8133de0406788135e16abbb Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 19 Feb 2010 12:35:50 +0100 Subject: qdoc: Finished "Inherited by" list for QML elements. The listed elements are now links. Task: QTBUG-8153 --- tools/qdoc3/cppcodeparser.cpp | 2 +- tools/qdoc3/generator.cpp | 26 ++++++++++++++++++++++++++ tools/qdoc3/generator.h | 7 +++++++ tools/qdoc3/htmlgenerator.cpp | 30 +++--------------------------- tools/qdoc3/node.cpp | 8 ++++---- tools/qdoc3/node.h | 6 +++--- 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 021d64a..d9e9c3b 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -1034,7 +1034,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, else if (command == COMMAND_QMLINHERITS) { setLink(node, Node::InheritsLink, arg); if (node->subType() == Node::QmlClass) { - QmlClassNode::addInheritedBy(arg,node->name()); + QmlClassNode::addInheritedBy(arg,node); } } else if (command == COMMAND_QMLDEFAULT) { diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 9b58d7f..d092f86 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -1213,6 +1213,32 @@ void Generator::appendSortedNames(Text& text, } } +void Generator::appendSortedNames(Text& text, + const Node* base, + const NodeList& subs, + CodeMarker *marker) +{ + NodeList::ConstIterator r; + QMap classMap; + int index = 0; + + r = subs.begin(); + while (r != subs.end()) { + Text className; + appendFullName(className, (*r), base, marker); + classMap[className.toString().toLower()] = className; + ++r; + } + + QStringList classNames = classMap.keys(); + classNames.sort(); + + foreach (const QString &className, classNames) { + text << classMap[className]; + text << separator(index++, classNames.count()); + } +} + int Generator::skipAtoms(const Atom *atom, Atom::Type type) const { int skipAhead = 0; diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 06f7f88..77dcfd4 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -170,6 +170,13 @@ class Generator const QList &classes, CodeMarker *marker); + protected: + void appendSortedNames(Text& text, + const Node* base, + const NodeList& subs, + CodeMarker *marker); + + private: QString amp; QString lt; QString gt; diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 01e79dd..45da0f1 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -4317,40 +4317,16 @@ void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn, CodeMarker* marker) { if (cn) { - QStringList subs; + NodeList subs; QmlClassNode::subclasses(cn->name(),subs); if (!subs.isEmpty()) { - subs.sort(); + //subs.sort(); Text text; text << Atom::ParaLeft << "Inherited by "; - for (int i = 0; i < subs.size(); ++i) { - text << subs.at(i); - text << separator(i, subs.size()); - } + appendSortedNames(text,cn,subs,marker); text << Atom::ParaRight; generateText(text, cn, marker); } -#if 0 - if (cn->links().contains(Node::InheritsLink)) { - QPair linkPair; - linkPair = cn->links()[Node::InheritsLink]; - QStringList strList(linkPair.first); - const Node* n = myTree->findNode(strList,Node::Fake); - if (n && n->subType() == Node::QmlClass) { - const QmlClassNode* qcn = static_cast(n); - out() << "

"; - Text text; - text << "[Inherits "; - text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); - text << Atom(Atom::String, linkPair.second); - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - text << "]"; - generateText(text, cn, marker); - out() << "

"; - } - } -#endif } } diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 4ddcfb1..5357597 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -1257,7 +1257,7 @@ bool TargetNode::isInnerNode() const #ifdef QDOC_QML bool QmlClassNode::qmlOnly = false; -QMultiMap QmlClassNode::inheritedBy; +QMultiMap QmlClassNode::inheritedBy; /*! Constructs a Qml class node (i.e. a Fake node with the @@ -1294,15 +1294,15 @@ QString QmlClassNode::fileBase() const Record the fact that QML class \a base is inherited by QML class \a sub. */ -void QmlClassNode::addInheritedBy(const QString& base, const QString& sub) +void QmlClassNode::addInheritedBy(const QString& base, Node* sub) { inheritedBy.insert(base,sub); } /*! - Loads the list \a subs with the names of all the subclasses of \a base. + Loads the list \a subs with the nodes of all the subclasses of \a base. */ -void QmlClassNode::subclasses(const QString& base, QStringList& subs) +void QmlClassNode::subclasses(const QString& base, NodeList& subs) { subs.clear(); if (inheritedBy.contains(base)) diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index de26025..3798e4e 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -383,12 +383,12 @@ class QmlClassNode : public FakeNode const ClassNode* classNode() const { return cnode; } virtual QString fileBase() const; - static void addInheritedBy(const QString& base, const QString& sub); - static void subclasses(const QString& base, QStringList& subs); + static void addInheritedBy(const QString& base, Node* sub); + static void subclasses(const QString& base, NodeList& subs); public: static bool qmlOnly; - static QMultiMap inheritedBy; + static QMultiMap inheritedBy; private: const ClassNode* cnode; -- cgit v0.12 From da1d0f7d34b7acdd4e38a8940279d9255eb15dc5 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Fri, 19 Feb 2010 13:26:27 +0100 Subject: Fix an issue about double-click on Mac OS X. A test is added when we double-click to verify that both pushed buttons are the same. --- src/gui/kernel/qt_cocoa_helpers_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index f2ec4af..71d6ff8 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -956,7 +956,7 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev #ifndef QT_NAMESPACE Q_ASSERT(clickCount > 0); #endif - if (clickCount % 2 == 0) + if (clickCount % 2 == 0 && buttons == button) eventType = QEvent::MouseButtonDblClick; if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) { button = Qt::RightButton; -- cgit v0.12 From 4607a42e3043c1201f4380e8090d8f66a71e10d1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 19 Feb 2010 13:36:02 +0100 Subject: Cocoa: event dispatcher eats mouse events It turns out that the event dispatcher did not flush queued user input events under some circumstances (when adding the exec-flag to processEvents). And this caused problems in the QML-editor in creator regarding focus frames. This patch makes sure that we always flush the queued user input events when calling processEvents. Task-number: QTBUG-8274 Reviewed-by: Prasanth Reviewed-by: cduclos --- src/gui/kernel/qeventdispatcher_mac.mm | 74 ++++++++++++++++------------------ 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index 8a67dee..b76ba44 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -565,6 +565,18 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags) QMacCocoaAutoReleasePool pool; NSEvent* event = 0; + // First, send all previously excluded input events, if any: + if (!(flags & QEventLoop::ExcludeUserInputEvents)) { + while (!d->queuedUserInputEvents.isEmpty()) { + event = static_cast(d->queuedUserInputEvents.takeFirst()); + if (!filterEvent(event)) { + qt_mac_send_event(flags, event, 0); + retVal = true; + } + [event release]; + } + } + // If Qt is used as a plugin, or as an extension in a native cocoa // application, we should not run or stop NSApplication; This will be // done from the application itself. And if processEvents is called @@ -598,49 +610,33 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags) // We cannot block the thread (and run in a tight loop). // Instead we will process all current pending events and return. d->ensureNSAppInitialized(); - do { - bool releaseEvent = false; - - if (!(flags & QEventLoop::ExcludeUserInputEvents) - && !d->queuedUserInputEvents.isEmpty()) { - // Process a pending user input event - releaseEvent = true; - event = static_cast(d->queuedUserInputEvents.takeFirst()); - } else { - if (NSModalSession session = d->currentModalSession()) { - if (flags & QEventLoop::WaitForMoreEvents) - qt_mac_waitForMoreModalSessionEvents(); - NSInteger status = [NSApp runModalSession:session]; - if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) { - // INVARIANT: Someone called [NSApp stopModal:] from outside the event - // dispatcher (e.g to stop a native dialog). But that call wrongly stopped - // 'session' as well. As a result, we need to restart all internal sessions: - d->temporarilyStopAllModalSessions(); - } - retVal = true; - break; - } else { - event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:nil - inMode:NSDefaultRunLoopMode - dequeue: YES]; - - if (event != nil) { - if (flags & QEventLoop::ExcludeUserInputEvents) { - if (IsMouseOrKeyEvent(event)) { - [event retain]; - d->queuedUserInputEvents.append(event); - continue; - } - } - } - } + if (NSModalSession session = d->currentModalSession()) { + if (flags & QEventLoop::WaitForMoreEvents) + qt_mac_waitForMoreModalSessionEvents(); + NSInteger status = [NSApp runModalSession:session]; + if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) { + // INVARIANT: Someone called [NSApp stopModal:] from outside the event + // dispatcher (e.g to stop a native dialog). But that call wrongly stopped + // 'session' as well. As a result, we need to restart all internal sessions: + d->temporarilyStopAllModalSessions(); } + retVal = true; + } else do { + event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:nil + inMode:NSDefaultRunLoopMode + dequeue: YES]; + if (event) { + if (flags & QEventLoop::ExcludeUserInputEvents) { + if (IsMouseOrKeyEvent(event)) { + [event retain]; + d->queuedUserInputEvents.append(event); + continue; + } + } if (!filterEvent(event) && qt_mac_send_event(flags, event, 0)) retVal = true; - if (releaseEvent) - [event release]; } } while (!d->interrupt && event != nil); -- cgit v0.12 From 7ca94f32c1a32ab96e4476388bea59d209dae4de Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 19 Feb 2010 14:23:57 +0100 Subject: doc: Added "\since 4.7" to a bunch of declarative stuff. --- .../graphicsitems/qmlgraphicsanchors.cpp | 1 + .../graphicsitems/qmlgraphicsanimatedimage.cpp | 1 + .../graphicsitems/qmlgraphicsborderimage.cpp | 3 +- .../graphicsitems/qmlgraphicsevents.cpp | 1 + .../graphicsitems/qmlgraphicsflipable.cpp | 1 + .../graphicsitems/qmlgraphicsfocuspanel.cpp | 1 + .../graphicsitems/qmlgraphicsfocusscope.cpp | 1 + .../qmlgraphicsgraphicsobjectcontainer.cpp | 1 + src/declarative/graphicsitems/qmlgraphicsimage.cpp | 1 + src/declarative/graphicsitems/qmlgraphicsitem.cpp | 7 ++++ .../graphicsitems/qmlgraphicslayoutitem.cpp | 1 + .../graphicsitems/qmlgraphicslistview.cpp | 1 + .../graphicsitems/qmlgraphicsloader.cpp | 1 + .../graphicsitems/qmlgraphicsmouseregion.cpp | 1 + .../graphicsitems/qmlgraphicsparticles.cpp | 23 +++++++++---- src/declarative/graphicsitems/qmlgraphicspath.cpp | 7 ++++ .../graphicsitems/qmlgraphicspathview.cpp | 1 + .../graphicsitems/qmlgraphicspositioners.cpp | 39 ++++++++++++++++------ .../graphicsitems/qmlgraphicsrectangle.cpp | 3 ++ .../graphicsitems/qmlgraphicsrepeater.cpp | 1 + src/declarative/graphicsitems/qmlgraphicstext.cpp | 1 + .../graphicsitems/qmlgraphicstextedit.cpp | 1 + .../graphicsitems/qmlgraphicstextinput.cpp | 1 + .../graphicsitems/qmlgraphicsvisualitemmodel.cpp | 1 + .../graphicsitems/qmlgraphicswebview.cpp | 1 + src/declarative/qml/qmlcomponent.cpp | 2 ++ src/declarative/qml/qmlcontext.cpp | 1 + src/declarative/qml/qmlengine.cpp | 2 ++ src/declarative/qml/qmlerror.cpp | 1 + src/declarative/qml/qmlexpression.cpp | 1 + src/declarative/qml/qmlmoduleplugin.cpp | 1 + .../qml/qmlnetworkaccessmanagerfactory.cpp | 1 + src/declarative/qml/qmlparserstatus.cpp | 1 + src/declarative/qml/qmlscriptstring.cpp | 1 + src/declarative/util/qmlanimation.cpp | 11 ++++++ src/declarative/util/qmlbind.cpp | 1 + src/declarative/util/qmlconnection.cpp | 1 + src/declarative/util/qmldatetimeformatter.cpp | 1 + src/declarative/util/qmlnumberformatter.cpp | 1 + src/declarative/util/qmlpropertychanges.cpp | 1 + src/declarative/util/qmlpropertymap.cpp | 1 + src/declarative/util/qmlstate.cpp | 1 + src/declarative/util/qmltransition.cpp | 1 + src/declarative/util/qmlview.cpp | 1 + src/declarative/util/qmlxmllistmodel.cpp | 2 ++ 45 files changed, 116 insertions(+), 18 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 3a6ec48..9bc4c09 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -125,6 +125,7 @@ static qreal adjustedPosition(QmlGraphicsItem *item, QmlGraphicsAnchorLine::Anch /*! \internal \class QmlGraphicsAnchors + \since 4.7 \ingroup group_layouts \brief The QmlGraphicsAnchors class provides a way to lay out items relative to other items. diff --git a/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp b/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp index eb60495..3eaa16f 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE /*! \qmlclass AnimatedImage QmlGraphicsAnimatedImage \inherits Image + \since 4.7 This item provides for playing animations stored as images containing a series of frames, such as GIF files. The full list of supported formats can be determined with diff --git a/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp b/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp index 493b148..a3b8e53 100644 --- a/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp @@ -56,6 +56,7 @@ QML_DEFINE_TYPE(Qt,4,6,BorderImage,QmlGraphicsBorderImage) \qmlclass BorderImage QmlGraphicsBorderImage \brief The BorderImage element provides an image that can be used as a border. \inherits Item + \since 4.7 \snippet snippets/declarative/border-image.qml 0 @@ -63,8 +64,8 @@ QML_DEFINE_TYPE(Qt,4,6,BorderImage,QmlGraphicsBorderImage) */ /*! - \internal \class QmlGraphicsBorderImage BorderImage + \internal \brief The QmlGraphicsBorderImage class provides an image item that you can add to a QmlView. */ diff --git a/src/declarative/graphicsitems/qmlgraphicsevents.cpp b/src/declarative/graphicsitems/qmlgraphicsevents.cpp index d42708c..3c828c4 100644 --- a/src/declarative/graphicsitems/qmlgraphicsevents.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsevents.cpp @@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE /*! \qmlclass KeyEvent QmlGraphicsKeyEvent + \since 4.7 \brief The KeyEvent object provides information about a key event. For example, the following changes the Item's state property when the Enter diff --git a/src/declarative/graphicsitems/qmlgraphicsflipable.cpp b/src/declarative/graphicsitems/qmlgraphicsflipable.cpp index a30ba6c..ef7bbc1 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflipable.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsflipable.cpp @@ -66,6 +66,7 @@ public: /*! \qmlclass Flipable QmlGraphicsFlipable + \since 4.7 \brief The Flipable item provides a surface that can be flipped. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp b/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp index 093e9de..2d0f782 100644 --- a/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp @@ -50,6 +50,7 @@ QML_DEFINE_TYPE(Qt,4,6,FocusPanel,QmlGraphicsFocusPanel) /*! \qmlclass FocusPanel QmlGraphicsFocusPanel + \since 4.7 \brief The FocusPanel item explicitly creates a focus panel. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp b/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp index 084e244..5d8c238 100644 --- a/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp @@ -46,6 +46,7 @@ QML_DEFINE_TYPE(Qt,4,6,FocusScope,QmlGraphicsFocusScope) /*! \qmlclass FocusScope QmlGraphicsFocusScope + \since 4.7 \brief The FocusScope object explicitly creates a focus scope. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp index e7206f1..6d33b80 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp @@ -83,6 +83,7 @@ public: /*! \qmlclass GraphicsObjectContainer QmlGraphicsGraphicsObjectContainer + \since 4.7 \brief The GraphicsObjectContainer element allows you to add QGraphicsObjects into Fluid UI elements. While any QObject based class can be exposed to QML, QmlGraphicsItem diff --git a/src/declarative/graphicsitems/qmlgraphicsimage.cpp b/src/declarative/graphicsitems/qmlgraphicsimage.cpp index d4ad3c8..6d60a87 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimage.cpp @@ -52,6 +52,7 @@ QML_DEFINE_TYPE(Qt,4,6,Image,QmlGraphicsImage) /*! \qmlclass Image QmlGraphicsImage + \since 4.7 \brief The Image element allows you to add bitmaps to a scene. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index 17362d0..cdfa24e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -79,6 +79,7 @@ QML_DEFINE_TYPE(Qt,4,6,Rotation,QGraphicsRotation) /*! \qmlclass Transform QGraphicsTransform + \since 4.7 \brief The Transform elements provide a way of building advanced transformations on Items. The Transform elements let you create and control advanced transformations that can be configured @@ -92,6 +93,7 @@ QML_DEFINE_TYPE(Qt,4,6,Rotation,QGraphicsRotation) /*! \qmlclass Scale QGraphicsScale + \since 4.7 \brief The Scale object provides a way to scale an Item. The Scale object gives more control over scaling than using Item's scale property. Specifically, @@ -130,6 +132,7 @@ QML_DEFINE_TYPE(Qt,4,6,Rotation,QGraphicsRotation) /*! \qmlclass Rotation QGraphicsRotation + \since 4.7 \brief The Rotation object provides a way to rotate an Item. The Rotation object gives more control over rotation than using Item's rotation property. @@ -391,6 +394,7 @@ void QmlGraphicsItemKeyFilter::componentComplete() /*! \qmlclass KeyNavigation + \since 4.7 \brief The KeyNavigation attached property supports key navigation by arrow keys. It is common in key-based UIs to use arrow keys to navigate @@ -639,6 +643,7 @@ void QmlGraphicsKeyNavigationAttached::keyReleased(QKeyEvent *event) /*! \qmlclass Keys + \since 4.7 \brief The Keys attached property provides key handling to Items. All visual primitives support key handling via the \e Keys @@ -1281,6 +1286,7 @@ QmlGraphicsKeysAttached *QmlGraphicsKeysAttached::qmlAttachedProperties(QObject /*! \class QmlGraphicsItem + \since 4.7 \brief The QmlGraphicsItem class provides the most basic of all visual items in QML. All visual items in Qt Declarative inherit from QmlGraphicsItem. Although QmlGraphicsItem @@ -1294,6 +1300,7 @@ QmlGraphicsKeysAttached *QmlGraphicsKeysAttached::qmlAttachedProperties(QObject /*! \qmlclass Item QmlGraphicsItem + \since 4.7 \brief The Item is the most basic of all visual items in QML. All visual items in Qt Declarative inherit from Item. Although Item diff --git a/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp b/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp index b054ced..8d2012f 100644 --- a/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp @@ -51,6 +51,7 @@ QML_DEFINE_TYPE(Qt,4,6,LayoutItem,QmlGraphicsLayoutItem) /*! \qmlclass LayoutItem QmlGraphicsLayoutItem + \since 4.7 \brief The LayoutItem element allows you to place your Fluid UI elements inside a classical Qt layout. */ diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index 1e2698c..eb408c3 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -1389,6 +1389,7 @@ void QmlGraphicsListViewPrivate::flickY(qreal velocity) /*! \qmlclass ListView QmlGraphicsListView + \since 4.7 \inherits Flickable \brief The ListView item provides a list view of items provided by a model. diff --git a/src/declarative/graphicsitems/qmlgraphicsloader.cpp b/src/declarative/graphicsitems/qmlgraphicsloader.cpp index 44932a2..bd4725a 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsloader.cpp @@ -112,6 +112,7 @@ QML_DEFINE_TYPE(Qt,4,6,Loader,QmlGraphicsLoader) /*! \qmlclass Loader QmlGraphicsLoader + \since 4.7 \inherits Item \brief The Loader item allows dynamically loading an Item-based diff --git a/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp b/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp index 1f8435e..099f685 100644 --- a/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp @@ -127,6 +127,7 @@ QmlGraphicsMouseRegionPrivate::~QmlGraphicsMouseRegionPrivate() /*! \qmlclass MouseRegion QmlGraphicsMouseRegion + \since 4.7 \brief The MouseRegion item enables simple mouse handling. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp index 95d4844..eef9571 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp @@ -157,6 +157,7 @@ void QmlGraphicsParticleMotion::destroy(QmlGraphicsParticle &particle) /*! \qmlclass ParticleMotionLinear + \since 4.7 \brief The ParticleMotionLinear object moves particles linearly. \sa Particles @@ -179,6 +180,7 @@ void QmlGraphicsParticleMotionLinear::advance(QmlGraphicsParticle &p, int interv /*! \qmlclass ParticleMotionGravity + \since 4.7 \brief The ParticleMotionGravity object moves particles towards a point. \sa Particles @@ -236,6 +238,7 @@ void QmlGraphicsParticleMotionGravity::advance(QmlGraphicsParticle &p, int inter /*! \qmlclass ParticleMotionWander + \since 4.7 \brief The ParticleMotionWander object moves particles in a somewhat random fashion. The particles will continue roughly in the original direction, however will randomly @@ -565,19 +568,25 @@ QML_DEFINE_TYPE(Qt,4,6,Particles,QmlGraphicsParticles) /*! \qmlclass Particles + \since 4.7 \brief The Particles object generates and moves particles. \inherits Item - This element provides preliminary support for particles in QML, and may be heavily changed or removed in later versions. + This element provides preliminary support for particles in QML, + and may be heavily changed or removed in later versions. - The particles created by this object cannot be dealt with directly, they can only be controlled through the parameters of the Particles object. The particles are all the same pixmap, specified by the user. + The particles created by this object cannot be dealt with + directly, they can only be controlled through the parameters of + the Particles object. The particles are all the same pixmap, + specified by the user. - The particles are painted relative to the parent of the Particles object. Moving the - Particles object will not move the particles already emitted. + The particles are painted relative to the parent of the Particles + object. Moving the Particles object will not move the particles + already emitted. - The below example creates two differently behaving particle sources. - The top one has particles falling from the top like snow, - the lower one has particles expelled up like a fountain. + The below example creates two differently behaving particle + sources. The top one has particles falling from the top like + snow, the lower one has particles expelled up like a fountain. \qml Rectangle { diff --git a/src/declarative/graphicsitems/qmlgraphicspath.cpp b/src/declarative/graphicsitems/qmlgraphicspath.cpp index 6f04b75..5c0683b 100644 --- a/src/declarative/graphicsitems/qmlgraphicspath.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspath.cpp @@ -60,6 +60,7 @@ QML_DEFINE_TYPE(Qt,4,6,PathCubic,QmlGraphicsPathCubic) /*! \qmlclass PathElement QmlGraphicsPathElement + \since 4.7 \brief PathElement is the base path type. This type is the base for all path types. It cannot @@ -76,6 +77,7 @@ QML_DEFINE_TYPE(Qt,4,6,PathCubic,QmlGraphicsPathCubic) /*! \qmlclass Path QmlGraphicsPath + \since 4.7 \brief A Path object defines a path for use by \l PathView. A Path is composed of one or more path segments - PathLine, PathQuad, @@ -476,6 +478,7 @@ void QmlGraphicsCurve::setY(qreal y) /*! \qmlclass PathAttribute QmlGraphicsPathAttribute + \since 4.7 \brief The PathAttribute allows setting an attribute at a given position in a Path. The PathAttribute object allows attibutes consisting of a name and @@ -555,6 +558,7 @@ void QmlGraphicsPathAttribute::setValue(qreal value) /*! \qmlclass PathLine QmlGraphicsPathLine + \since 4.7 \brief The PathLine defines a straight line. The example below creates a path consisting of a straight line from @@ -595,6 +599,7 @@ void QmlGraphicsPathLine::addToPath(QPainterPath &path) /*! \qmlclass PathQuad QmlGraphicsPathQuad + \since 4.7 \brief The PathQuad defines a quadratic Bezier curve with a control point. The following QML produces the path shown below: @@ -679,6 +684,7 @@ void QmlGraphicsPathQuad::addToPath(QPainterPath &path) /*! \qmlclass PathCubic QmlGraphicsPathCubic + \since 4.7 \brief The PathCubic defines a cubic Bezier curve with two control points. The following QML produces the path shown below: @@ -789,6 +795,7 @@ void QmlGraphicsPathCubic::addToPath(QPainterPath &path) /*! \qmlclass PathPercent QmlGraphicsPathPercent + \since 4.7 \brief The PathPercent manipulates the way a path is interpreted. The examples below show the normal distrubution of items along a path diff --git a/src/declarative/graphicsitems/qmlgraphicspathview.cpp b/src/declarative/graphicsitems/qmlgraphicspathview.cpp index 4511820..101c2c6 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspathview.cpp @@ -138,6 +138,7 @@ void QmlGraphicsPathViewPrivate::releaseItem(QmlGraphicsItem *item) /*! \qmlclass PathView QmlGraphicsPathView + \since 4.7 \brief The PathView element lays out model-provided items on a path. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp index ba26f62..e3306f2 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp @@ -291,6 +291,7 @@ void QmlGraphicsBasePositioner::finishApplyTransitions() QML_DEFINE_TYPE(Qt,4,6,Column,QmlGraphicsColumn) /*! \qmlclass Column QmlGraphicsColumn + \since 4.7 \brief The Column item lines up its children vertically. \inherits Item @@ -340,19 +341,28 @@ Column { */ /*! \qmlproperty Transition Column::add - This property holds the transition to be applied when adding an item to the positioner. The transition will only be applied to the added item(s). - Positioner transitions will only affect the position (x,y) of items. - Added can mean that either the object has been created or reparented, and thus is now a child or the positioner, or that the object has had its opacity increased from zero, and thus is now visible. + This property holds the transition to be applied when adding an + item to the positioner. The transition will only be applied to the + added item(s). Positioner transitions will only affect the + position (x,y) of items. + + Added can mean that either the object has been created or + reparented, and thus is now a child or the positioner, or that the + object has had its opacity increased from zero, and thus is now + visible. */ /*! \qmlproperty Transition Column::move - This property holds the transition to apply when moving an item within the positioner. - Positioner transitions will only affect the position (x,y) of items. - This can happen when other items are added or removed from the positioner, or when items resize themselves. + This property holds the transition to apply when moving an item + within the positioner. Positioner transitions will only affect + the position (x,y) of items. + + This can happen when other items are added or removed from the + positioner, or when items resize themselves. \table \row @@ -421,6 +431,7 @@ void QmlGraphicsColumn::doPositioning() QML_DEFINE_TYPE(Qt,4,6,Row,QmlGraphicsRow) /*! \qmlclass Row QmlGraphicsRow + \since 4.7 \brief The Row item lines up its children horizontally. \inherits Item @@ -456,16 +467,22 @@ Row { The transition will only be applied to the added item(s). Positioner transitions will only affect the position (x,y) of items. - Added can mean that either the object has been created or reparented, and thus is now a child or the positioner, or that the object has had its opacity increased from zero, and thus is now visible. + Added can mean that either the object has been created or + reparented, and thus is now a child or the positioner, or that the + object has had its opacity increased from zero, and thus is now + visible. */ /*! \qmlproperty Transition Row::move - This property holds the transition to apply when moving an item within the positioner. - Positioner transitions will only affect the position (x,y) of items. - This can happen when other items are added or removed from the positioner, or when items resize themselves. + This property holds the transition to apply when moving an item + within the positioner. Positioner transitions will only affect + the position (x,y) of items. + + This can happen when other items are added or removed from the + positioner, or when items resize themselves. \qml Row { @@ -527,6 +544,7 @@ QML_DEFINE_TYPE(Qt,4,6,Grid,QmlGraphicsGrid) /*! \qmlclass Grid QmlGraphicsGrid + \since 4.7 \brief The Grid item positions its children in a grid. \inherits Item @@ -714,6 +732,7 @@ void QmlGraphicsGrid::doPositioning() QML_DEFINE_TYPE(Qt,4,6,Flow,QmlGraphicsFlow) /*! \qmlclass Flow QmlGraphicsFlow + \since 4.7 \brief The Flow item lines up its children side by side, wrapping as necessary. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp b/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp index 1fa63e0..25ddaf5 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp @@ -86,6 +86,7 @@ void QmlGraphicsPen::setWidth(int w) /*! \qmlclass GradientStop QmlGraphicsGradientStop + \since 4.7 \brief The GradientStop item defines the color at a position in a Gradient \sa Gradient @@ -106,6 +107,7 @@ void QmlGraphicsGradientStop::updateGradient() /*! \qmlclass Gradient QmlGraphicsGradient + \since 4.7 \brief The Gradient item defines a gradient fill. A gradient is defined by two or more colors, which will be blended seemlessly. The @@ -153,6 +155,7 @@ QML_DEFINE_TYPE(Qt,4,6,Rectangle,QmlGraphicsRectangle) /*! \qmlclass Rectangle QmlGraphicsRectangle + \since 4.7 \brief The Rectangle item allows you to add rectangles to a scene. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp b/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp index 0c27f4c..899de0d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp @@ -64,6 +64,7 @@ QML_DEFINE_TYPE(Qt,4,6,Repeater,QmlGraphicsRepeater) /*! \qmlclass Repeater QmlGraphicsRepeater + \since 4.7 \inherits Item \brief The Repeater item allows you to repeat a component based on a model. diff --git a/src/declarative/graphicsitems/qmlgraphicstext.cpp b/src/declarative/graphicsitems/qmlgraphicstext.cpp index e9e5924..4d228dd 100644 --- a/src/declarative/graphicsitems/qmlgraphicstext.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstext.cpp @@ -59,6 +59,7 @@ QML_DEFINE_TYPE(Qt,4,6,Text,QmlGraphicsText) /*! \qmlclass Text QmlGraphicsText + \since 4.7 \brief The Text item allows you to add formatted text to a scene. \inherits Item diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp index e8cde10..5d410be 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp @@ -60,6 +60,7 @@ QML_DEFINE_TYPE(Qt,4,6,TextEdit,QmlGraphicsTextEdit) /*! \qmlclass TextEdit QmlGraphicsTextEdit + \since 4.7 \brief The TextEdit item allows you to add editable formatted text to a scene. It can display both plain and rich text. For example: diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp index a7b25c5..56e0610 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp @@ -59,6 +59,7 @@ QML_DEFINE_TYPE(Qt,4,6,QRegExpValidator,QRegExpValidator); /*! \qmlclass TextInput QmlGraphicsTextInput + \since 4.7 The TextInput item allows you to add an editable line of text to a scene. TextInput can only display a single line of text, and can only display diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index f9ebef9..ae045ae 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -140,6 +140,7 @@ public: /*! \qmlclass VisualItemModel QmlGraphicsVisualItemModel + \since 4.7 \brief The VisualItemModel allows items to be provided to a view. The children of the VisualItemModel are provided in a model which diff --git a/src/declarative/graphicsitems/qmlgraphicswebview.cpp b/src/declarative/graphicsitems/qmlgraphicswebview.cpp index a811506..5b6b34e 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicswebview.cpp @@ -124,6 +124,7 @@ public: /*! \qmlclass WebView QmlGraphicsWebView + \since 4.7 \brief The WebView item allows you to add web content to a canvas. \inherits Item diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index f15c364..2b62887 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -69,12 +69,14 @@ int statusId = qRegisterMetaType("QmlComponent::Status"); /*! \class QmlComponent + \since 4.7 \brief The QmlComponent class encapsulates a QML component description. \mainclass */ /*! \qmlclass Component QmlComponent + \since 4.7 \brief The Component element encapsulates a QML component description. Components are reusable, encapsulated Qml element with a well-defined interface. diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 4011d8d..c540cc2 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -130,6 +130,7 @@ void QmlContextPrivate::init() /*! \class QmlContext + \since 4.7 \brief The QmlContext class defines a context within a QML engine. \mainclass diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index bb36035..01bc6d3 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -112,6 +112,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) QML_DEFINE_TYPE(Qt,4,6,QtObject,QObject) /*! \qmlclass QtObject QObject + \since 4.7 \brief The QtObject element is the most basic element in QML The QtObject element is a non-visual element which contains only @@ -333,6 +334,7 @@ QmlWorkerScriptEngine *QmlEnginePrivate::getWorkerScriptEngine() /*! \class QmlEngine + \since 4.7 \brief The QmlEngine class provides an environment for instantiating QML components. \mainclass diff --git a/src/declarative/qml/qmlerror.cpp b/src/declarative/qml/qmlerror.cpp index 5ba7719..fc4bcd5 100644 --- a/src/declarative/qml/qmlerror.cpp +++ b/src/declarative/qml/qmlerror.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlError + \since 4.7 \brief The QmlError class encapsulates a QML error */ class QmlErrorPrivate diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index d428377..89870f9 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -189,6 +189,7 @@ QScriptValue QmlExpressionPrivate::evalInObjectScope(QmlContext *context, QObjec /*! \class QmlExpression + \since 4.7 \brief The QmlExpression class evaluates JavaScript in a QML context. */ diff --git a/src/declarative/qml/qmlmoduleplugin.cpp b/src/declarative/qml/qmlmoduleplugin.cpp index 8019805..342074a 100644 --- a/src/declarative/qml/qmlmoduleplugin.cpp +++ b/src/declarative/qml/qmlmoduleplugin.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlModulePlugin + \since 4.7 \brief The QmlModulePlugin class provides an abstract base for custom QML module plugins. \reentrant \ingroup plugins diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp index 1ba0694..455d09e 100644 --- a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp +++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlNetworkAccessManagerFactory + \since 4.7 \brief The QmlNetworkAccessManagerFactory class provides a factory for QNetworkAccessManager QNetworkAccessManager is used for all network access by QML. diff --git a/src/declarative/qml/qmlparserstatus.cpp b/src/declarative/qml/qmlparserstatus.cpp index 435d620..315bc75 100644 --- a/src/declarative/qml/qmlparserstatus.cpp +++ b/src/declarative/qml/qmlparserstatus.cpp @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlParserStatus + \since 4.7 \brief The QmlParserStatus class provides updates on the parser state. */ diff --git a/src/declarative/qml/qmlscriptstring.cpp b/src/declarative/qml/qmlscriptstring.cpp index 29118e6..a80f66b 100644 --- a/src/declarative/qml/qmlscriptstring.cpp +++ b/src/declarative/qml/qmlscriptstring.cpp @@ -55,6 +55,7 @@ public: /*! \class QmlScriptString + \since 4.7 \brief The QmlScriptString class encapsulates a script and its context. The QmlScriptString is used by properties that want to accept a script "assignment" from QML. diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index 103a50f..37c0044 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -143,6 +143,7 @@ QML_DEFINE_NOCREATE_TYPE(QmlAbstractAnimation) /*! \qmlclass Animation QmlAbstractAnimation + \since 4.7 \brief The Animation element is the base of all QML animations. The Animation element cannot be used directly in a QML file. It exists @@ -567,6 +568,7 @@ void QmlAbstractAnimation::timelineComplete() /*! \qmlclass PauseAnimation QmlPauseAnimation + \since 4.7 \inherits Animation \brief The PauseAnimation element provides a pause for an animation. @@ -640,6 +642,7 @@ QAbstractAnimation *QmlPauseAnimation::qtAnimation() /*! \qmlclass ColorAnimation QmlColorAnimation + \since 4.7 \inherits PropertyAnimation \brief The ColorAnimation element allows you to animate color changes. @@ -703,6 +706,7 @@ QML_DEFINE_TYPE(Qt,4,6,ColorAnimation,QmlColorAnimation) /*! \qmlclass ScriptAction QmlScriptAction + \since 4.7 \inherits Animation \brief The ScriptAction element allows scripts to be run during an animation. @@ -809,6 +813,7 @@ QML_DEFINE_TYPE(Qt,4,6,ScriptAction,QmlScriptAction) /*! \qmlclass PropertyAction QmlPropertyAction + \since 4.7 \inherits Animation \brief The PropertyAction element allows immediate property changes during animation. @@ -1108,6 +1113,7 @@ QML_DEFINE_TYPE(Qt,4,6,PropertyAction,QmlPropertyAction) /*! \qmlclass ParentAction QmlParentAction + \since 4.7 \inherits Animation \brief The ParentAction element allows parent changes during animation. @@ -1330,6 +1336,7 @@ QML_DEFINE_TYPE(Qt,4,6,ParentAction,QmlParentAction) /*! \qmlclass NumberAnimation QmlNumberAnimation + \since 4.7 \inherits PropertyAnimation \brief The NumberAnimation element allows you to animate changes in properties of type qreal. @@ -1393,6 +1400,7 @@ QML_DEFINE_TYPE(Qt,4,6,NumberAnimation,QmlNumberAnimation) /*! \qmlclass Vector3dAnimation QmlVector3dAnimation + \since 4.7 \inherits PropertyAnimation \brief The Vector3dAnimation element allows you to animate changes in properties of type QVector3d. */ @@ -1466,6 +1474,7 @@ QmlList *QmlAnimationGroup::animations() /*! \qmlclass SequentialAnimation QmlSequentialAnimation + \since 4.7 \inherits Animation \brief The SequentialAnimation element allows you to run animations sequentially. @@ -1541,6 +1550,7 @@ QML_DEFINE_TYPE(Qt,4,6,SequentialAnimation,QmlSequentialAnimation) /*! \qmlclass ParallelAnimation QmlParallelAnimation + \since 4.7 \inherits Animation \brief The ParallelAnimation element allows you to run animations in parallel. @@ -1665,6 +1675,7 @@ void QmlPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) /*! \qmlclass PropertyAnimation QmlPropertyAnimation + \since 4.7 \inherits Animation \brief The PropertyAnimation element allows you to animate property changes. diff --git a/src/declarative/util/qmlbind.cpp b/src/declarative/util/qmlbind.cpp index fc1562b..6743edd 100644 --- a/src/declarative/util/qmlbind.cpp +++ b/src/declarative/util/qmlbind.cpp @@ -71,6 +71,7 @@ public: QML_DEFINE_TYPE(Qt,4,6,Binding,QmlBind) /*! \qmlclass Binding QmlBind + \since 4.7 \brief The Binding element allows arbitrary property bindings to be created. Sometimes it is necessary to bind to a property of an object that wasn't diff --git a/src/declarative/util/qmlconnection.cpp b/src/declarative/util/qmlconnection.cpp index 9bec3bb..c03d618 100644 --- a/src/declarative/util/qmlconnection.cpp +++ b/src/declarative/util/qmlconnection.cpp @@ -66,6 +66,7 @@ public: /*! \qmlclass Connection QmlConnection + \since 4.7 \brief A Connection object describes generalized connections to signals. When connecting to signals in QML, the usual way is to create an diff --git a/src/declarative/util/qmldatetimeformatter.cpp b/src/declarative/util/qmldatetimeformatter.cpp index c44ca5e..4b8fb00 100644 --- a/src/declarative/util/qmldatetimeformatter.cpp +++ b/src/declarative/util/qmldatetimeformatter.cpp @@ -74,6 +74,7 @@ public: /*! \qmlclass DateTimeFormatter QmlDateTimeFormatter + \since 4.7 \brief The DateTimeFormatter allows you to control the format of a date string. \code diff --git a/src/declarative/util/qmlnumberformatter.cpp b/src/declarative/util/qmlnumberformatter.cpp index f78abdf..0845d0c 100644 --- a/src/declarative/util/qmlnumberformatter.cpp +++ b/src/declarative/util/qmlnumberformatter.cpp @@ -67,6 +67,7 @@ public: }; /*! \qmlclass NumberFormatter + \since 4.7 \brief The NumberFormatter allows you to control the format of a number string. The format property documentation has more details on how the format can be manipulated. diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index 84f1e9a..b26469e 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE /*! \qmlclass PropertyChanges QmlPropertyChanges + \since 4.7 \brief The PropertyChanges element describes new property values for a state. PropertyChanges provides a state change that modifies the properties of an item. diff --git a/src/declarative/util/qmlpropertymap.cpp b/src/declarative/util/qmlpropertymap.cpp index ccbec6f..317896e 100644 --- a/src/declarative/util/qmlpropertymap.cpp +++ b/src/declarative/util/qmlpropertymap.cpp @@ -90,6 +90,7 @@ void QmlPropertyMapMetaObject::propertyWrite(int index) /*! \class QmlPropertyMap + \since 4.7 \brief The QmlPropertyMap class allows you to set key-value pairs that can be used in bindings. QmlPropertyMap provides a convenient way to expose domain data to the UI layer. diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp index 7ecbd79..d550b6f 100644 --- a/src/declarative/util/qmlstate.cpp +++ b/src/declarative/util/qmlstate.cpp @@ -130,6 +130,7 @@ QmlStateOperation::QmlStateOperation(QObjectPrivate &dd, QObject *parent) /*! \qmlclass State QmlState + \since 4.7 \brief The State element defines configurations of objects and properties. A state is specified as a set of batched changes from the default configuration. diff --git a/src/declarative/util/qmltransition.cpp b/src/declarative/util/qmltransition.cpp index 22826ce..792f795 100644 --- a/src/declarative/util/qmltransition.cpp +++ b/src/declarative/util/qmltransition.cpp @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE /*! \qmlclass Transition QmlTransition + \since 4.7 \brief The Transition element defines animated transitions that occur on state changes. \sa {qmlstates}{States}, {state-transitions}{Transitions} diff --git a/src/declarative/util/qmlview.cpp b/src/declarative/util/qmlview.cpp index 702b054..7518118 100644 --- a/src/declarative/util/qmlview.cpp +++ b/src/declarative/util/qmlview.cpp @@ -152,6 +152,7 @@ public: /*! \class QmlView + \since 4.7 \brief The QmlView class provides a widget for displaying a Qt Declarative user interface. QmlView currently provides a minimal interface for displaying QML diff --git a/src/declarative/util/qmlxmllistmodel.cpp b/src/declarative/util/qmlxmllistmodel.cpp index 7975959..f765dce 100644 --- a/src/declarative/util/qmlxmllistmodel.cpp +++ b/src/declarative/util/qmlxmllistmodel.cpp @@ -65,6 +65,7 @@ QML_DEFINE_TYPE(Qt,4,6,XmlListModel,QmlXmlListModel) /*! \qmlclass XmlRole QmlXmlListModelRole + \since 4.7 \brief The XmlRole element allows you to specify a role for an XmlListModel. */ @@ -406,6 +407,7 @@ void QmlXmlRoleList::insert(int i, QmlXmlListModelRole *role) /*! \qmlclass XmlListModel QmlXmlListModel + \since 4.7 \brief The XmlListModel element allows you to specify a model using XPath expressions. XmlListModel allows you to construct a model from XML data that can then be used as a data source -- cgit v0.12 From 09dc6df0472957d75f6c99cf81c939cb9a31602c Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 19 Feb 2010 14:24:27 +0100 Subject: Work around MSVC2008 compiler crash "e:\pulse\work\91088\src\script\api\qscriptengine.h(360) : fatal error C1001: An internal error has occurred in the compiler. (compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c[0x510A0530:0x00000007]', line 243) To work around this problem, try simplifying or changing the program near the locations listed above." Apparently the compiler doesn't like that a few functions are inlined. --- src/script/api/qscriptengine.cpp | 15 +++++++++++++++ src/script/api/qscriptengine_p.h | 13 ++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 739b3fc..33104c9 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -393,6 +393,21 @@ qsreal ToInteger(qsreal n) return sign * ::floor(::fabs(n)); } +#ifdef Q_CC_MSVC +// MSVC2008 crashes if these are inlined. + +QString ToString(qsreal value) +{ + return JSC::UString::from(value); +} + +qsreal ToNumber(const QString &value) +{ + return ((JSC::UString)value).toDouble(); +} + +#endif + void GlobalClientData::mark(JSC::MarkStack& markStack) { engine->mark(markStack); diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index eff34af..f69e537 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -106,12 +106,18 @@ namespace QScript inline bool ToBool(qsreal); inline bool ToBool(const QString &); - inline qsreal ToNumber(const QString &); inline qint32 ToInt32(const QString &); inline quint32 ToUInt32(const QString &); inline quint16 ToUInt16(const QString &); inline qsreal ToInteger(const QString &); +#ifdef Q_CC_MSVC + // MSVC2008 crashes if these are inlined. + qsreal ToNumber(const QString &); + QString ToString(qsreal); +#else + inline qsreal ToNumber(const QString &); inline QString ToString(qsreal); +#endif //some conversion helper functions inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); @@ -463,6 +469,9 @@ inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) return static_cast(exec->globalData().clientData)->engine; } +#ifndef Q_CC_MSVC +// MSVC2008 crashes if these are inlined. + inline QString ToString(qsreal value) { return JSC::UString::from(value); @@ -473,6 +482,8 @@ inline qsreal ToNumber(const QString &value) return ((JSC::UString)value).toDouble(); } +#endif + inline qint32 ToInt32(const QString &value) { return ToInt32(ToNumber(value)); -- cgit v0.12 From 85e5372c53c342f54cd489a3233c00aefa3d7ff7 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 19 Feb 2010 14:41:52 +0100 Subject: Doc: Simplified Commercial Editions for Qt 4.7. Reviewed-by: Trust Me Requested-by: Sales and Legal --- doc/src/development/qmake-manual.qdoc | 2 +- doc/src/frameworks-technologies/activeqt.qdoc | 2 +- doc/src/getting-started/installation.qdoc | 2 +- doc/src/index.qdoc | 2 +- doc/src/legal/commercialeditions.qdoc | 79 +++--------------------- doc/src/legal/editions.qdoc | 4 +- doc/src/legal/licenses.qdoc | 2 +- doc/src/legal/opensourceedition.qdoc | 1 - doc/src/modules.qdoc | 61 +++--------------- doc/src/platforms/mac-differences.qdoc | 2 +- doc/src/xml-processing/xml-patterns.qdoc | 3 +- src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc | 3 - tools/qdoc3/generator.cpp | 27 -------- tools/qdoc3/generator.h | 1 - tools/qdoc3/htmlgenerator.cpp | 1 - tools/qdoc3/test/qt-build-docs.qdocconf | 8 --- tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf | 8 --- tools/qdoc3/test/qt.qdocconf | 7 --- 18 files changed, 23 insertions(+), 192 deletions(-) diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 6215268..6406193 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -872,7 +872,7 @@ Developers using Visual Studio to write Qt applications can use the Visual Studio integration facilities provided with the - \l{Qt Commercial Editions} and do not need to worry about how + \l{Qt Commercial Edition} and do not need to worry about how project dependencies are managed. However, some developers may need to import an existing \c qmake project diff --git a/doc/src/frameworks-technologies/activeqt.qdoc b/doc/src/frameworks-technologies/activeqt.qdoc index 67b9bb3..e24959d 100644 --- a/doc/src/frameworks-technologies/activeqt.qdoc +++ b/doc/src/frameworks-technologies/activeqt.qdoc @@ -93,7 +93,7 @@ plugin that integrates the QAxContainer module into \l{Qt Designer}. - The ActiveQt modules are part of the \l{Qt Full Framework Edition} and + The ActiveQt modules are part of the \l{Qt Commercial Edition} and the \l{Open Source Versions of Qt}. \sa {QAxContainer Module}, {QAxServer Module} diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index e54774b..b23629d 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -176,7 +176,7 @@ consult the installation instructions provided instead of the ones in this document. \o \l{Open Source Versions of Qt} is not officially supported for use with any version of Visual Studio. Integration with Visual Studio is available -as part of the \l{Qt Commercial Editions}. +as part of the \l{Qt Commercial Edition}. \endlist \endtable diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index d1f5f0f..52d4488 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -142,7 +142,7 @@ diff --git a/doc/src/legal/commercialeditions.qdoc b/doc/src/legal/commercialeditions.qdoc index 4e44376..dde8d69 100644 --- a/doc/src/legal/commercialeditions.qdoc +++ b/doc/src/legal/commercialeditions.qdoc @@ -40,61 +40,19 @@ ****************************************************************************/ /*! - \page commercialeditions.html - \title Qt Commercial Editions + \page commercialedition.html + \title Qt Commercial Edition \ingroup licensing \brief Information about the license and features of the Commercial Edition. - \keyword Qt Full Framework Edition - \keyword Qt GUI Framework Edition - - Two editions of Qt are available under a commercial license: - Qt GUI Framework Edition, and Qt Full Framework Edition. + Qt can be used to develop closed source software if you obtain a commercial + license. If you want to develop Free or Open Source software for release using a recognized Open Source license, you can use the \l{Open Source Versions of Qt}. The table below summarizes the differences between the two commercial editions: - \table 75% - \header \o{1,2} Features \o{2,1} Editions - \header \o Qt GUI Framework \o Qt Full Framework - \row \o \l{QtCore}{Qt Core classes (QtCore)} \o \bold{X} \o \bold{X} - \row \o \l{QtGui}{Qt GUI classes (QtGui)} \o \bold{(X)} \o \bold{X} - \row \o \l{Graphics View Classes} (part of QtGui) \o \o \bold{X} - \row \o \l{QtNetwork}{Networking (QtNetwork)} \o \o \bold{X} - \row \o \l{QtOpenGL}{OpenGL (QtOpenGL)} \o \o \bold{X} - \row \o \l{QtScript}{Scripting (QtScript)} \o \o \bold{X} - \row \o \l{QtScriptTools}{Script Debugging (QtScriptTools)}\o \o \bold{X} - \row \o \l{QtSql}{Database/SQL (QtSql)} \o \o \bold{X} - \row \o \l{QtSvg}{SVG (QtSvg)} \o \o \bold{X} - \row \o \l{QtWebKit}{WebKit integration (QtWebKit)} \o \o \bold{X} - \row \o \l{QtXml}{XML (QtXml)} \o \o \bold{X} - \row \o \l{QtXmlPatterns}{XQuery and XPath (QtXmlPatterns)}\o \o \bold{X} - \row \o \l{Qt3Support}{Qt 3 Support (Qt3Support)} \o \bold{(X)} \o \bold{X} - \row \o \l{QtHelp}{Help system (QtHelp)} \o \o \bold{X} - \row \o \l{QtDBus}{D-Bus IPC support (QtDBus)} \o \bold{X} \o \bold{X} - \row \o \l{QtDesigner}{\QD extension classes (QtDesigner)} \o \o \bold{X} - \row \o \l{QtTest}{Unit testing framework (QtTest)} \o \bold{X} \o \bold{X} - \row \o \l{QtUiTools}{Run-time form handling (QtUiTools)} \o \o \bold{X} - \row \o \l{Phonon Module}{Phonon Multimedia Framework} \o \o \bold{X} - \row \o \l{ActiveQt} \o \o \bold{} - \endtable - - \bold{(X)} The Qt GUI Framework Edition contains selected classes from the QtGui and - Qt3Support modules corresponding to the functionality available in the Qt 3 Professional - Edition. - - \bold{} The ActiveQt module is only available on Windows. - - Lists of the classes available in each edition are available on the - following pages: - - \list - \o \l{Qt GUI Framework Edition} - \o \l{Qt Full Framework Edition} - \endlist - Please see the \l{Supported Platforms}{list of supported platforms} for up-to-date information about the various platforms and compilers that Qt supports. @@ -103,36 +61,13 @@ \l{Qt Licensing Overview} and information on \l{Qt License Pricing} for commercial editions of Qt and other Qt-related products. - To purchase, please visit the \l{How to Order}{online order - form}. + To purchase, please visit the \l{How to Order}{online order form}. - For further information and assistance, please contact Qt - sales. + For further information and assistance, please contact Qt sales. Web: http://qt.nokia.com/contact. Phone, U.S. office (for North America): \bold{1-650-813-1676}. - Phone, Norway office (for the rest of the world): \bold{+47 21 60 - 48 00}. -*/ - -/*! - \page full-framework-edition-classes.html - \title Qt Full Framework Edition - \ingroup classlists - - \brief The list of Qt classes included in the Full Framework Edition. - - \generatelist{classesbyedition Desktop} -*/ - -/*! - \page gui-framework-edition-classes.html - \title Qt GUI Framework Edition - \ingroup classlists - - \brief The list of Qt classes included in the GUI Framework Edition. - - \generatelist{classesbyedition DesktopLight} + Phone, Norway office (for the rest of the world): \bold{+47 21 60 48 00}. */ diff --git a/doc/src/legal/editions.qdoc b/doc/src/legal/editions.qdoc index 4de77c1..c7e73f2 100644 --- a/doc/src/legal/editions.qdoc +++ b/doc/src/legal/editions.qdoc @@ -53,8 +53,8 @@ In terms of license conditions, there are two main forms of Qt: \list - \o The \l{Qt Commercial Editions} are the commercial - versions of \l{About Qt}{Qt}. + \o The \l{Qt Commercial Edition} is the commercial version of + \l{About Qt}{Qt} which can be used to create closed source software. \o The \l{Open Source Versions of Qt} are freely available for download. \endlist diff --git a/doc/src/legal/licenses.qdoc b/doc/src/legal/licenses.qdoc index 344ebd4..d1bf4cf 100644 --- a/doc/src/legal/licenses.qdoc +++ b/doc/src/legal/licenses.qdoc @@ -60,7 +60,7 @@ Qt contains some code that is not provided under the \l{GNU General Public License (GPL)}, \l{GNU Lesser General Public License (LGPL)} or the - \l{Qt Commercial Editions}{Qt Commercial License Agreement}, but rather under + \l{Qt Commercial Edition}{Qt Commercial License Agreement}, but rather under specific licenses from the original authors. Some pieces of code were developed by Nokia and others originated from third parties. This page lists the licenses used, names the authors, and links diff --git a/doc/src/legal/opensourceedition.qdoc b/doc/src/legal/opensourceedition.qdoc index c199e34..d95e107 100644 --- a/doc/src/legal/opensourceedition.qdoc +++ b/doc/src/legal/opensourceedition.qdoc @@ -87,5 +87,4 @@ If you are in doubt what edition of Qt is right for your project, please contact \l{mailto:qt-info@nokia.com}{qt-info@nokia.com}. - */ diff --git a/doc/src/modules.qdoc b/doc/src/modules.qdoc index 78af7eb..9e1d340 100644 --- a/doc/src/modules.qdoc +++ b/doc/src/modules.qdoc @@ -109,8 +109,6 @@ definitions of the module's classes, use the following directive: \snippet doc/src/snippets/code/doc_src_qtcore.qdoc 0 - - The QtCore module is part of all \l{Qt editions}. */ @@ -128,9 +126,6 @@ following directive: \snippet doc/src/snippets/code/doc_src_qtgui.qdoc 0 - - The QtGui module is part of the \l{Qt GUI Framework Edition}, - the \l{Qt Full Framework Edition}, and the \l{Open Source Versions of Qt}. */ /*! @@ -177,9 +172,6 @@ .pro file: \snippet doc/src/snippets/code/doc_src_qtnetwork.qdoc 0 - - The QtNetwork module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. */ /*! @@ -225,9 +217,9 @@ OpenGL module can take advantage of the whole Qt API for non-OpenGL-specific GUI functionality. - The QtOpenGL module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. It is available on Windows, X11, and Mac OS X. - \l{Qt for Embedded Linux and OpenGL} supports OpenGL ES (OpenGL for Embedded Systems). + The QtOpenGL module is available on Windows, X11 and Mac OS X. + \l{Qt for Embedded Linux and OpenGL} supports OpenGL ES (OpenGL for + Embedded Systems). \note To be able to use the OpenGL API in \l{Qt for Embedded Linux}, it must be integrated with the Q Window System (QWS). See the \l{Qt for Embedded Linux and OpenGL} documentation for details. @@ -319,9 +311,6 @@ scriptable with QtScript, see \l{Making Applications Scriptable}. - The QtScript module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. - \section1 License Information Qt Commercial Edition licensees that wish to distribute applications that @@ -379,9 +368,6 @@ To link against the module, add this line to your \l qmake \c .pro file: \snippet doc/src/snippets/code/doc.src.qtscripttools.qdoc 1 - - The QtScriptTools module is part of the \l{Qt Full Framework Edition} and - the \l{Open Source Versions of Qt}. */ /*! @@ -402,9 +388,6 @@ \snippet doc/src/snippets/code/doc_src_qtsql.qdoc 1 - The QtSql module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. - See the \l{SQL Programming} guide for information about using this module in your applications. */ @@ -430,9 +413,6 @@ \snippet doc/src/snippets/code/doc_src_qtsvg.qdoc 1 - The QtSvg module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. - \section1 License Information Some code for arc handling in this module is derived from code with @@ -488,9 +468,6 @@ Further XML support is provided by the \l{Qt Solutions} group who provide, for example, classes that support SOAP and MML with the Qt XML classes. - - This module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. */ /*! @@ -515,9 +492,6 @@ \snippet doc/src/snippets/code/doc_src_qtxmlpatterns.qdoc 1 - This module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. - \section1 License Information The XML Schema implementation provided by this module contains the \c xml.xsd file @@ -594,9 +568,6 @@ \snippet doc/src/snippets/code/doc_src_phonon.qdoc 1 - The Phonon module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. - \section1 Qt Backends Qt Backends are currently developed for Phonon version 4.1. The Phonon @@ -672,12 +643,6 @@ diverse parts of the Qt 3 API, it has dependencies on the QtCore, QtGui, QtNetwork, QtSql, and QtXml modules. - This module is part of the \l{Qt Full Framework Edition} and the - \l{Open Source Versions of Qt}. Most classes offered by this module are - also part of the \l{Qt GUI Framework Edition}. - Classes that are not available for \l{Qt GUI Framework Edition} - users are marked as such in the class documentation. - \sa {Porting to Qt 4} */ @@ -705,10 +670,6 @@ file: \snippet doc/src/snippets/code/doc_src_qtdesigner.qdoc 1 - - \note These classes are part of the \l{Open Source Versions of Qt} and - \l{Qt Commercial Editions}{Qt Full Framework Edition} for commercial - users. */ /*! @@ -745,10 +706,6 @@ \snippet doc/src/snippets/code/doc_src_qtuiloader.qdoc 1 - \note These classes are part of the \l{Open Source Versions of Qt} and - \l{Qt Commercial Editions}{Qt Full Framework Edition} for commercial - users. - \sa{Calculator Builder Example}, {World Time Clock Builder Example} */ @@ -773,10 +730,6 @@ \snippet doc/src/snippets/code/doc_src_qthelp.qdoc 1 - These classes are part of the \l{Open Source Versions of Qt} and - \l{Qt Commercial Editions}{Qt Full Framework Edition} for commercial - users. - \section1 License Information The QtHelp module uses the CLucene indexing library to provide full-text @@ -860,7 +813,7 @@ The QAxContainer module is not covered by the \l{GNU General Public License (GPL)}, the \l{GNU Lesser General Public License (LGPL)}, or the - \l{Qt Commercial Editions}{Qt Commercial License}. Instead, it is distributed under + \l{Qt Commercial Edition}{Qt Commercial License}. Instead, it is distributed under the following license. \legalese @@ -910,7 +863,7 @@ The QAxContainer module is not covered by the \l{GNU General Public License (GPL)}, the \l{GNU Lesser General Public License (LGPL)}, or the - \l{Qt Commercial Editions}{Qt Commercial License}. Instead, it is distributed under + \l{Qt Commercial Edition}{Qt Commercial License}. Instead, it is distributed under the following license. \legalese @@ -1005,7 +958,7 @@ The QAxContainer module is not covered by the \l{GNU General Public License (GPL)}, the \l{GNU Lesser General Public License (LGPL)}, or the - \l{Qt Commercial Editions}{Qt Commercial License}. Instead, it is distributed under + \l{Qt Commercial Edition}{Qt Commercial License}. Instead, it is distributed under the following license. \legalese @@ -1043,7 +996,7 @@ located in the \c{src/s60main} directory are not covered by the \l{GNU General Public License (GPL)}, the \l{GNU Lesser General Public License (LGPL)}, or the - \l{Qt Commercial Editions}{Qt Commercial License}. Instead, they are + \l{Qt Commercial Edition}{Qt Commercial License}. Instead, they are distributed under the following license. \legalese diff --git a/doc/src/platforms/mac-differences.qdoc b/doc/src/platforms/mac-differences.qdoc index bda439d..58d64de 100644 --- a/doc/src/platforms/mac-differences.qdoc +++ b/doc/src/platforms/mac-differences.qdoc @@ -301,7 +301,7 @@ \contentspage {Other Licenses Used in Qt}{Contents} \ingroup licensing - \brief License information for contributions by Apple, Inc. to specific parts of the Qt/Mac Cocoa port. + \brief License information for contributions by Apple, Inc. to specific parts of the Qt for Mac OS X Cocoa port. \legalese diff --git a/doc/src/xml-processing/xml-patterns.qdoc b/doc/src/xml-processing/xml-patterns.qdoc index 408b2da..68056fd 100644 --- a/doc/src/xml-processing/xml-patterns.qdoc +++ b/doc/src/xml-processing/xml-patterns.qdoc @@ -65,8 +65,7 @@ \l{http://www.w3.org/TR/xpath20} {XPath 2.0} in Qt applications, for querying XML data \e{and} for querying \l{QAbstractXmlNodeModel} {non-XML data that can be modeled to - look like XML}. The QtXmlPatterns module is included in the \l{Qt - Full Framework Edition}, and the \l{Open Source Versions of Qt}. + look like XML}. Readers who are not familiar with the XQuery/XPath language can read \l {A Short Path to XQuery} for a brief introduction. diff --git a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc index 411762a..9e653e4 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc +++ b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc @@ -83,9 +83,6 @@ QtWebKit is based on the Open Source WebKit engine. More information about WebKit itself can be found on the \l{WebKit Open Source Project} Web site. - The QtWebKit module is part of the \l{Qt Full Framework Edition}, and the - \l{Open Source Versions of Qt}. - \note Building the QtWebKit module with debugging symbols is problematic on many platforms due to the size of the WebKit engine. We recommend building the module only in release mode for embedded platforms. diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 9b58d7f..6a8899a 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -641,33 +641,6 @@ void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker) } #endif -void Generator::generateModuleWarning(const ClassNode *classe, - CodeMarker *marker) -{ - QString module = classe->moduleName(); - if (!module.isEmpty()) { - Text text; - if (!editionModuleMap["DesktopLight"].contains(module)) { - text << Atom::ParaLeft - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) - << "This class is not part of the Qt GUI Framework Edition." - << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) - << Atom::ParaRight; - } - else if (module == "Qt3Support") { - text << Atom::ParaLeft - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) - << "Note to Qt GUI Framework Edition users:" - << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) - << " This class is only available in the " - << Atom(Atom::AutoLink, "Qt Full Framework Edition") - << "." << Atom::ParaRight; - } - - generateText(text, classe, marker); - } -} - QString Generator::indent(int level, const QString& markedCode) { if (level == 0) diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 06f7f88..44f56e2 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -124,7 +124,6 @@ class Generator Node::SubType subtype, const QString& tag); void generateExampleFiles(const FakeNode *fake, CodeMarker *marker); - void generateModuleWarning(const ClassNode *classe, CodeMarker *marker); virtual int skipAtoms(const Atom *atom, Atom::Type type) const; virtual QString fullName(const Node *node, diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 01e79dd..e767460 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1261,7 +1261,6 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, generateIncludes(inner, marker); generateStatus(inner, marker); if (classe) { - generateModuleWarning(classe, marker); generateInherits(classe, marker); generateInheritedBy(classe, marker); } diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index 555e826..fb2c3c1 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -12,14 +12,6 @@ sourceencoding = UTF-8 outputencoding = UTF-8 naturallanguage = en_US -edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript \ - QtScriptTools QtSql QtSvg QtWebKit QtXml QtXmlPatterns \ - Qt3Support QtHelp QtDesigner QtAssistant QAxContainer Phonon \ - QAxServer QtUiTools QtTest QtDBus - -edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest -edition.DesktopLight.groups = -graphicsview-api - qhp.projects = Qt qhp.Qt.file = qt.qhp diff --git a/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf index 18b72a1..7a77f54 100644 --- a/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf +++ b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf @@ -14,14 +14,6 @@ naturallanguage = zh-Hans indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index -edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript \ - QtScriptTools QtSql QtSvg QtWebKit QtXml QtXmlPatterns \ - Qt3Support QtHelp QtDesigner QtAssistant QAxContainer Phonon \ - QAxServer QtUiTools QtTest QtDBus - -edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest -edition.DesktopLight.groups = -graphicsview-api - qhp.projects = Qt qhp.Qt.file = qt.qhp diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf index f7757fb..d8b9136 100644 --- a/tools/qdoc3/test/qt.qdocconf +++ b/tools/qdoc3/test/qt.qdocconf @@ -14,13 +14,6 @@ sourceencoding = UTF-8 outputencoding = UTF-8 naturallanguage = en_US -edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript \ - QtScriptTools QtSql QtSvg QtWebKit QtXml QtXmlPatterns \ - Qt3Support QtHelp QtDesigner QtAssistant QAxContainer Phonon \ - QAxServer QtUiTools QtTest QtDBus -edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest -edition.DesktopLight.groups = -graphicsview-api - qhp.projects = Qt qhp.Qt.file = qt.qhp -- cgit v0.12 From d049509ba60b90f28c12db83c74e22649384e48c Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 19 Feb 2010 14:43:19 +0100 Subject: Doc: Collected the Declarative UI tutorials together and renamed them. Reviewed-by: Trust Me --- doc/src/declarative/advtutorial.qdoc | 317 ++++++++++++++++++++++++++++++++- doc/src/declarative/advtutorial1.qdoc | 82 --------- doc/src/declarative/advtutorial2.qdoc | 107 ----------- doc/src/declarative/advtutorial3.qdoc | 116 ------------ doc/src/declarative/advtutorial4.qdoc | 159 ----------------- doc/src/declarative/declarativeui.qdoc | 4 +- doc/src/declarative/examples.qdoc | 2 +- doc/src/declarative/qmlreference.qdoc | 4 +- doc/src/declarative/tutorial.qdoc | 189 +++++++++++++++++++- doc/src/declarative/tutorial1.qdoc | 97 ---------- doc/src/declarative/tutorial2.qdoc | 112 ------------ doc/src/declarative/tutorial3.qdoc | 86 --------- 12 files changed, 498 insertions(+), 777 deletions(-) delete mode 100644 doc/src/declarative/advtutorial1.qdoc delete mode 100644 doc/src/declarative/advtutorial2.qdoc delete mode 100644 doc/src/declarative/advtutorial3.qdoc delete mode 100644 doc/src/declarative/advtutorial4.qdoc delete mode 100644 doc/src/declarative/tutorial1.qdoc delete mode 100644 doc/src/declarative/tutorial2.qdoc delete mode 100644 doc/src/declarative/tutorial3.qdoc diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc index 10c53d5..87c040e 100644 --- a/doc/src/declarative/advtutorial.qdoc +++ b/doc/src/declarative/advtutorial.qdoc @@ -40,8 +40,10 @@ ****************************************************************************/ /*! -\page advtutorial.html -\title Advanced Tutorial +\page qml-advtutorial.html +\title QML Advanced Tutorial +\brief A more advanced tutorial, showing how to use QML to create a game. +\nextpage QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks This tutorial goes step-by-step through creating a full application using just QML. It is assumed that you already know basic QML (such as from doing the simple tutorial) and the focus is on showing @@ -55,10 +57,313 @@ The results of the individual steps are in the $QTDIR/examples/declarative/tutor Tutorial chapters: \list -\o \l {Advanced Tutorial 1 - Creating the Game Canvas and Blocks} -\o \l {Advanced Tutorial 2 - Populating the Game Canvas} -\o \l {Advanced Tutorial 3 - Implementing the Game Logic} -\o \l {Advanced Tutorial 4 - Finishing Touches} +\o \l {QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks} +\o \l {QML Advanced Tutorial 2 - Populating the Game Canvas} +\o \l {QML Advanced Tutorial 3 - Implementing the Game Logic} +\o \l {QML Advanced Tutorial 4 - Finishing Touches} \endlist +*/ + +/*! +\page qml-advtutorial1.html +\title QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks +\contentspage QML Advanced Tutorial +\previouspage QML Advanced Tutorial +\nextpage QML Advanced Tutorial 2 - Populating the Game Canvas + +The first step is to create the items in your application. In Same Game we have a main game screen and the blocks that populate it. + +\image declarative-adv-tutorial1.png + +Here is the QML code for the basic elements. The game window: + +\snippet declarative/tutorials/samegame/samegame1/samegame.qml 0 + +This gives you a basic game window, with room for the game canvas. A new game +button and room to display the score. The one thing you may not recognize here +is the \l SystemPalette item. This item provides access to the Qt system palette +and is used to make the button look more like a system button (for exact native +feel you would use a \l QPushButton). Since we want a fully QML button, and QML does +not include a button, we had to write our own. Below is the code which we wrote to do this: + +\snippet declarative/tutorials/samegame/samegame1/Button.qml 0 + +Note that this Button component was written to be fairly generic, in case we +want to use a similarly styled button later. + +And here is a simple block: + +\snippet declarative/tutorials/samegame/samegame1/Block.qml 0 + +Since it doesn't do anything yet it's very simple, just an image. As the +tutorial progresses and the block starts doing things the file will become +more than just an image. Note that we've set the image to be the size of the item. +This will be used later, when we dynamically create and size the block items the image will be scaled automatically +to the correct size. + +You should be familiar with all that goes on in these files so far. This is a +very basic start and doesn't move at all - next we will populate the game canvas +with some blocks. +*/ + + +/*! +\page qml-advtutorial2.html +\title QML Advanced Tutorial 2 - Populating the Game Canvas +\contentspage QML Advanced Tutorial +\previouspage QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks +\nextpage QML Advanced Tutorial 3 - Implementing the Game Logic + +Now that we've written some basic elements, let's start writing the game. The +first thing to do is to generate all of the blocks. Now we need to dynamically +generate all of these blocks, because you have a new, random set of blocks +every time. As they are dynamically generated every time the new game button is +clicked, as opposed to on startup, we will be dynamically generating the blocks +in the JavaScript, as opposed to using a \l Repeater. + +This adds enough script to justify a new file, \c{samegame.js}, the intial version +of which is shown below + +\snippet declarative/tutorials/samegame/samegame2/samegame.js 0 + +The gist of this code is that we create the blocks dynamically, as many as will fit, and then store them in an array for future reference. +The \c initBoard function will be hooked up to the new game button soon, and should be fairly straight forward. + +The \c createBlock function is a lot bigger, and I'll explain it block by block. +First we ensure that the component has been constructed. QML elements, including composite ones like the \c Block.qml +that we've written, are never created directly in script. While there is a function to parse and create an arbitrary QML string, +in the case where you are repeatedly creating the same item you will want to use the \c createComponent function. \c createComponent is +a built-in function in the declarative JavaScript, and returns a component object. +A component object prepares and stores a QML element (usually a composite element) for easy and efficient use. +When the component is ready, you can create a new instance of the loaded QML with the \c createObject method. +If the component is loaded remotely (over HTTP for example) then you will have to wait for the component to finish loading +before calling \c createObject. Since we don't wait here (the waiting is asyncronous, the component object will send a signal to tell +you when it's done) this code will only work if the block QML is a local file. + +As we aren't waiting for the component, the next block of code creates a game block with \c{component.createObject}. +Since there could be an error in the QML file you are trying to load, success is not guaranteed. +The first bit of error checkign code comes right after \c{createObject()}, to ensure that the object loaded correctly. +If it did not load correctly the function returns false, but we don't have that hooked up to the main UI to indicate +that something has gone wrong. Instead we print out error messages to the console, because an error here means an invalid +QML file and should only happen while you are developing and testing the UI. + +Next we start to set up our dynamically created block. +Because the \c{Block.qml} file is generic it needs to be placed in the main scene, and in the right place. +This is why \c parent, \c x, \c y, \c width and \c height are set. We then store it in the board array for later use. + +Finally, we have some more error handling. You can only call \c{createObject} if the component has loaded. +If it has not loaded, either it is still loading or there was an error loading (such as a missing file). +Since we don't request remote files the problem is likely to be a missing or misplaced file. +Again we print this to the console to aid debugging. + +You now have the code to create a field of blocks dynamically, like below: + +\image declarative-adv-tutorial2.png + +To hook this code up to the \e{New Game} button, you alter it as below: + +\snippet declarative/tutorials/samegame/samegame2/samegame.qml 1 + +We have just replaced the \c{onClicked: console.log("Implement me!")} with \c{onClicked: initBoard()}. +Note that in order to have the function available, you'll need to include the script in the main file, +by adding a script element to it. + +\snippet declarative/tutorials/samegame/samegame2/samegame.qml 2 + +With those two changes, and the script file, you are now dynamically creating a field of blocks you can play with. +They don't do anything now though; the next chapter will add the game mechanics. +*/ + +/*! +\page qml-advtutorial3.html +\title QML Advanced Tutorial 3 - Implementing the Game Logic +\contentspage QML Advanced Tutorial +\previouspage QML Advanced Tutorial 2 - Populating the Game Canvas +\nextpage QML Advanced Tutorial 4 - Finishing Touches + +First we add to the \c initBoard function clearing of the board before filling it up again, so that clicking new game won't leave the previous game +lying around in the background. To the \c createComponent function we have added setting the type of the block to a number between +one and three - it's fundamental to the game logic that the blocks be different types if you want a fun game. + +The main change was adding the following game logic functions: +\list +\o function \c{handleClick(x,y)} +\o function \c{floodFill(xIdx,yIdx,type)} +\o function \c{shuffleDown()} +\o function \c{victoryCheck()} +\o function \c{floodMoveCheck(xIdx, yIdx, type)} +\endlist + +As this is a tutorial about QML, not game design, these functions will not be discussed in detail. The game logic here +was written in script, but it could have been written in C++ and had these functions exposed in the same way (except probably faster). +The interfacing of these functions and QML is what we will focus on. Of these functions, only \c handleClick and \c victoryCheck +interface closely with the QML. Those functions are shown below (the rest are still in the code for this tutorial located at +\c{$QTDIR/examples/declarative/tutorials/samegame}). + +\snippet declarative/tutorials/samegame/samegame3/samegame.js 1 +\snippet declarative/tutorials/samegame/samegame3/samegame.js 2 + +You'll notice them referring to the \c gameCanvas item. This is an item that has been added to the QML for easier interfacing with the game logic. +It is placed next to the background image and replaces the background as the item to create the blocks in. +Its code is shown below: + +\snippet declarative/tutorials/samegame/samegame3/samegame.qml 1 + +This item is the exact size of the board, contains a score property, and a mouse region for input. +The blocks are now created as its children, and its size is used to determining the board size, so as to scale to the available screen size. +Since it needs to bind its size to a multiple of \c tileSize, \c tileSize needs to be moved into a QML property and out of the script file. +Note that it can still be accessed from the script. + +The mouse region simply calls \c{handleClick()}, which deals with the input events. +Should those events cause the player to score, \c{gameCanvas.score} is updated. +The score display text item has also been changed to bind its text property to \c{gamecanvas.score}. +Note that if score was a global variable in the \c{samegame.js} file you could not bind to it. You can only bind to QML properties. + +\c victoryCheck() primarily updates the score variable. But it also pops up a dialog saying \e {Game Over} when the game is over. +In this example we wanted a pure-QML, animated dialog, and since QML doesn't contain one, we wrote our own. +Below is the code for the \c Dialog element, note how it's designed so as to be usable imperatively from within the script file (via the functions and signals): + +\snippet declarative/tutorials/samegame/samegame3/Dialog.qml 0 + +And this is how it's used in the main QML file: + +\snippet declarative/tutorials/samegame/samegame3/samegame.qml 2 + +Combined with the line of code in \c victoryCheck, this causes a dialog to appear when the game is over, informing the user of that fact. + +We now have a working game! The blocks can be clicked, the player can score, and the game can end (and then you start a new one). +Below is a screenshot of what has been accomplished so far: + +\image declarative-adv-tutorial3.png + +Here is the QML code as it is now for the main file: + +\snippet declarative/tutorials/samegame/samegame3/samegame.qml 0 + +And the code for the block: + +\snippet declarative/tutorials/samegame/samegame3/Block.qml 0 + +The game works, but it's a little boring right now. Where are the smooth animated transitions? Where are the high scores? +If you were a QML expert you could have written these in for the first iteration, but in this tutorial they've been saved +until the next chapter - where your application becomes alive! +*/ + +/*! +\page qml-advtutorial4.html +\title QML Advanced Tutorial 4 - Finishing Touches +\contentspage QML Advanced Tutorial +\previouspage QML Advanced Tutorial 3 - Implementing the Game Logic + +Now we're going to do two things to liven the game up. Animate the blocks and add a web-based high score system. + +If you compare the \c samegame3 directory with \c samegame4, you'll noticed that we've cleaned the directory structure up. +We now have a lot of files, and so they've been split up into folders - the most notable one being a content folder +which we've placed all the QML but the main file. + +\section2 Animated Blocks + +The most vital animations are that the blocks move fluidly around the board. QML has many tools for fluid behavior, +and in this case we're going to use the \l SpringFollow element. By having the script set \c targetX and \c targetY, instead of \c x +and \c y directly, we can set the \c x and \c y of the block to a follow. \l SpringFollow is a property value source, which means +that you can set a property to be one of these elements and it will automatically bind the property to the element's value. +The SpringFollow's value follows another value over time, when the value it is tracking changes the SpringFollow's +value will also change, but it will move smoothly there over time with a spring-like movement (based on the spring +parameters specified). This is shown in the below snippet of code from \c Block.qml: + +\code + property int targetX: 0 + property int targetY: 0 + + x: SpringFollow { source: targetX; spring: 2; damping: 0.2 } + y: SpringFollow { source: targetY; spring: 2; damping: 0.2 } +\endcode + +We also have to change the \c{samegame.js} code, so that wherever it was setting the \c x or \c y it now sets \c targetX and \c targetY +(including when creating the block). This simple change is all you need to get spring moving blocks that no longer teleport +around the board. If you try doing just this though, you'll notice that they now never jump from one point to another, even in +the initialization! This gives an odd effect of having them all slide out of the corner (0,0) on start up. We'd rather that they +fall down from the top in rows. To do this, we disable the \c x follow (but not the \c y follow) and only enable it after we've set +the \c x in the \c createBlock function. The above snippet now becomes: + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 1 + +The next-most vital animation is a smooth exit. For this animation, we'll use a \l Behavior element. A Behavior is also a property +value source, and it is much like SpringFollow except that it doesn't model the behavior of a spring. You specify how a Behavior +transitions using the standard animations. As we want the blocks to smoothly fade in and out we'll set a Behavior on the block +image's opacity, like so: + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 2 + +Note that the \c{opacity: 0} makes it start out transparent. We could set the opacity in the script file when we create and destroy the blocks, +but instead we use states (as this is useful for the next animation we'll implement). The below snippet is set on the root +element of \c{Block.qml}: +\code + property bool dying: false + states: [ + State{ name: "AliveState"; when: spawned == true && dying == false + PropertyChanges { target: img; opacity: 1 } + }, State{ name: "DeathState"; when: dying == true + PropertyChanges { target: img; opacity: 0 } + } + ] +\endcode + +Now it will automatically fade in, as we set spawned to true already when implementing the block movement animations. +To fade out, we set 'dying' to true instead of setting opacity to 0 when a block is destroyed (in the \c floodFill function). + +The least vital animations are a cool-looking particle effect when they get destroyed. First we create a \l Particles element in +the block, like so: + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 3 + +To fully understand this you'll want to look at the Particles element documentation, but it's important to note that emissionRate is set +to zero, so that no particles are emitted normally. +We next extend the 'dying' state, which creates a burst of particles by calling the burst method on the particles element. The code for the states now look +like this: + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 4 + +And now the game should be beautifully animated and smooth, with a subtle (or not-so-subtle) animation added for all of the +player's actions. The end result is shown below, with a different set of images to demonstrate basic themeing: + +\image declarative-adv-tutorial4.gif + +The basic theme change there is the result of simply replacing the images. This can be done at run time by setting the source property, so a further advanced feature to try on your own is to add a button which toggles between two different themes. + +\section2 Offline High Scores +Another extension we might want for the game is some way of storing and retrieving high scores. This tutorial contains both online and offline high score storage. + +For better high score data, we want the name and time of the player. The time is obtained in the script fairly simply, but we +have to ask the player for their name. We thus re-use the dialog QML file to pop up a dialog asking for the player's name (and +if they exit this dialog without entering it they have a way to opt out of posting their high score). When the dialog is closed we store the name and high score, using the code below. + +\snippet declarative/tutorials/samegame/samegame4/content/samegame.js 2 + +For offline storage, we use the HTML 5 offline storage JavaScript API to maintain a persistant SQL database unique to this application. This first line in this function calls the function for the web-based high scores, described later, if it has been setup. Next we create an offline storage database for the high scores using openDatabase and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrival, and in the db.transaction call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string. For a more detailed explanation of the offline storage API in QML, consult the global object documentation. + +This is one way of storing and displaying high scores locally, but not the only way. A more complex alternative would have been to create a high score dialog component, and pass the results to it for processing and display (instead of resusing the Dialog). This would allow a more themable dialog that could present the high scores better. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database. + +\section2 Web-based High Scores + +You've seen how to store high scores locally, but it is also easy to integrate a web enabled high score storage into your QML application. This tutorial also shows you how to communicate the high scores to a web server. The implementation we've done is very +simple - the high score data is posted to a php script running on a server somewhere, and that server then stores it and +displays it to visitors. You could request an XML or QML file from that same server, which contained and displayed the scores, +but that's beyond the scope of this tutorial. The php script we've used is available in the examples directory. + +if the player entered their name we can send the data to the web service in the following snippet out of the script file: + +\snippet declarative/tutorials/samegame/samegame4/content/samegame.js 1 + +This is the same \c XMLHttpRequest() as you'll find in browser JavaScript, and can be used in the same way to dynamically get XML +or QML from the web service to display the high scores. We don't worry about the response in this case, we just post the high +score data to the web server. If it had returned a QML file (or a URL to a QML file) you could instantiate it in much the same +way as you did the blocks. + +An alternate way to access and submit web-based data would be to use QML elements designed for this purpose - XmlListModel +makes it very easy to fetch and display XML based data such as RSS in a QML application (see the Flickr demo for an example). +By following this tutorial you've now ben shown how to write a fully functional application in QML, with the application logic +written in a script file and with both many fluid animations and being web-enabled. Congratulations, you should now be skilled +enough to write entire applications in QML. */ diff --git a/doc/src/declarative/advtutorial1.qdoc b/doc/src/declarative/advtutorial1.qdoc deleted file mode 100644 index 598537a..0000000 --- a/doc/src/declarative/advtutorial1.qdoc +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page advtutorial1.html -\title Advanced Tutorial 1 - Creating the Game Canvas and Blocks - -The first step is to create the items in your application. In Same Game we have a main game screen and the blocks that populate it. - -\image declarative-adv-tutorial1.png - -Here is the QML code for the basic elements. The game window: - -\snippet declarative/tutorials/samegame/samegame1/samegame.qml 0 - -This gives you a basic game window, with room for the game canvas. A new game -button and room to display the score. The one thing you may not recognize here -is the \l SystemPalette item. This item provides access to the Qt system palette -and is used to make the button look more like a system button (for exact native -feel you would use a \l QPushButton). Since we want a fully QML button, and QML does -not include a button, we had to write our own. Below is the code which we wrote to do this: - -\snippet declarative/tutorials/samegame/samegame1/Button.qml 0 - -Note that this Button component was written to be fairly generic, in case we -want to use a similarly styled button later. - -And here is a simple block: - -\snippet declarative/tutorials/samegame/samegame1/Block.qml 0 - -Since it doesn't do anything yet it's very simple, just an image. As the -tutorial progresses and the block starts doing things the file will become -more than just an image. Note that we've set the image to be the size of the item. -This will be used later, when we dynamically create and size the block items the image will be scaled automatically -to the correct size. - -You should be familiar with all that goes on in these files so far. This is a -very basic start and doesn't move at all - next we will populate the game canvas -with some blocks. - -[\l {advtutorial.html}{Advanced Tutorial}] [Next: \l {Advanced Tutorial 2 - Populating the Game Canvas}] -*/ - diff --git a/doc/src/declarative/advtutorial2.qdoc b/doc/src/declarative/advtutorial2.qdoc deleted file mode 100644 index 1addf45..0000000 --- a/doc/src/declarative/advtutorial2.qdoc +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page advtutorial2.html -\title Advanced Tutorial 2 - Populating the Game Canvas - -Now that we've written some basic elements, let's start writing the game. The -first thing to do is to generate all of the blocks. Now we need to dynamically -generate all of these blocks, because you have a new, random set of blocks -every time. As they are dynamically generated every time the new game button is -clicked, as opposed to on startup, we will be dynamically generating the blocks -in the JavaScript, as opposed to using a \l Repeater. - -This adds enough script to justify a new file, \c{samegame.js}, the intial version -of which is shown below - -\snippet declarative/tutorials/samegame/samegame2/samegame.js 0 - -The gist of this code is that we create the blocks dynamically, as many as will fit, and then store them in an array for future reference. -The \c initBoard function will be hooked up to the new game button soon, and should be fairly straight forward. - -The \c createBlock function is a lot bigger, and I'll explain it block by block. -First we ensure that the component has been constructed. QML elements, including composite ones like the \c Block.qml -that we've written, are never created directly in script. While there is a function to parse and create an arbitrary QML string, -in the case where you are repeatedly creating the same item you will want to use the \c createComponent function. \c createComponent is -a built-in function in the declarative JavaScript, and returns a component object. -A component object prepares and stores a QML element (usually a composite element) for easy and efficient use. -When the component is ready, you can create a new instance of the loaded QML with the \c createObject method. -If the component is loaded remotely (over HTTP for example) then you will have to wait for the component to finish loading -before calling \c createObject. Since we don't wait here (the waiting is asyncronous, the component object will send a signal to tell -you when it's done) this code will only work if the block QML is a local file. - -As we aren't waiting for the component, the next block of code creates a game block with \c{component.createObject}. -Since there could be an error in the QML file you are trying to load, success is not guaranteed. -The first bit of error checkign code comes right after \c{createObject()}, to ensure that the object loaded correctly. -If it did not load correctly the function returns false, but we don't have that hooked up to the main UI to indicate -that something has gone wrong. Instead we print out error messages to the console, because an error here means an invalid -QML file and should only happen while you are developing and testing the UI. - -Next we start to set up our dynamically created block. -Because the \c{Block.qml} file is generic it needs to be placed in the main scene, and in the right place. -This is why \c parent, \c x, \c y, \c width and \c height are set. We then store it in the board array for later use. - -Finally, we have some more error handling. You can only call \c{createObject} if the component has loaded. -If it has not loaded, either it is still loading or there was an error loading (such as a missing file). -Since we don't request remote files the problem is likely to be a missing or misplaced file. -Again we print this to the console to aid debugging. - -You now have the code to create a field of blocks dynamically, like below: - -\image declarative-adv-tutorial2.png - -To hook this code up to the \e{New Game} button, you alter it as below: - -\snippet declarative/tutorials/samegame/samegame2/samegame.qml 1 - -We have just replaced the \c{onClicked: console.log("Implement me!")} with \c{onClicked: initBoard()}. -Note that in order to have the function available, you'll need to include the script in the main file, -by adding a script element to it. - -\snippet declarative/tutorials/samegame/samegame2/samegame.qml 2 - -With those two changes, and the script file, you are now dynamically creating a field of blocks you can play with. -They don't do anything now though; the next chapter will add the game mechanics. - -[Previous: \l {Advanced Tutorial 1 - Creating the Game canvas and block}] [\l {advtutorial.html}{Advanced Tutorial}] [Next: \l {Advanced Tutorial 3 - Implementing the Game Logic}] - -*/ diff --git a/doc/src/declarative/advtutorial3.qdoc b/doc/src/declarative/advtutorial3.qdoc deleted file mode 100644 index d101a98..0000000 --- a/doc/src/declarative/advtutorial3.qdoc +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page advtutorial3.html -\title Advanced Tutorial 3 - Implementing the Game Logic - -First we add to the \c initBoard function clearing of the board before filling it up again, so that clicking new game won't leave the previous game -lying around in the background. To the \c createComponent function we have added setting the type of the block to a number between -one and three - it's fundamental to the game logic that the blocks be different types if you want a fun game. - -The main change was adding the following game logic functions: -\list -\o function \c{handleClick(x,y)} -\o function \c{floodFill(xIdx,yIdx,type)} -\o function \c{shuffleDown()} -\o function \c{victoryCheck()} -\o function \c{floodMoveCheck(xIdx, yIdx, type)} -\endlist - -As this is a tutorial about QML, not game design, these functions will not be discussed in detail. The game logic here -was written in script, but it could have been written in C++ and had these functions exposed in the same way (except probably faster). -The interfacing of these functions and QML is what we will focus on. Of these functions, only \c handleClick and \c victoryCheck -interface closely with the QML. Those functions are shown below (the rest are still in the code for this tutorial located at -\c{$QTDIR/examples/declarative/tutorials/samegame}). - -\snippet declarative/tutorials/samegame/samegame3/samegame.js 1 -\snippet declarative/tutorials/samegame/samegame3/samegame.js 2 - -You'll notice them referring to the \c gameCanvas item. This is an item that has been added to the QML for easier interfacing with the game logic. -It is placed next to the background image and replaces the background as the item to create the blocks in. -Its code is shown below: - -\snippet declarative/tutorials/samegame/samegame3/samegame.qml 1 - -This item is the exact size of the board, contains a score property, and a mouse region for input. -The blocks are now created as its children, and its size is used to determining the board size, so as to scale to the available screen size. -Since it needs to bind its size to a multiple of \c tileSize, \c tileSize needs to be moved into a QML property and out of the script file. -Note that it can still be accessed from the script. - -The mouse region simply calls \c{handleClick()}, which deals with the input events. -Should those events cause the player to score, \c{gameCanvas.score} is updated. -The score display text item has also been changed to bind its text property to \c{gamecanvas.score}. -Note that if score was a global variable in the \c{samegame.js} file you could not bind to it. You can only bind to QML properties. - -\c victoryCheck() primarily updates the score variable. But it also pops up a dialog saying \e {Game Over} when the game is over. -In this example we wanted a pure-QML, animated dialog, and since QML doesn't contain one, we wrote our own. -Below is the code for the \c Dialog element, note how it's designed so as to be usable imperatively from within the script file (via the functions and signals): - -\snippet declarative/tutorials/samegame/samegame3/Dialog.qml 0 - -And this is how it's used in the main QML file: - -\snippet declarative/tutorials/samegame/samegame3/samegame.qml 2 - -Combined with the line of code in \c victoryCheck, this causes a dialog to appear when the game is over, informing the user of that fact. - -We now have a working game! The blocks can be clicked, the player can score, and the game can end (and then you start a new one). -Below is a screenshot of what has been accomplished so far: - -\image declarative-adv-tutorial3.png - -Here is the QML code as it is now for the main file: - -\snippet declarative/tutorials/samegame/samegame3/samegame.qml 0 - -And the code for the block: - -\snippet declarative/tutorials/samegame/samegame3/Block.qml 0 - -The game works, but it's a little boring right now. Where are the smooth animated transitions? Where are the high scores? -If you were a QML expert you could have written these in for the first iteration, but in this tutorial they've been saved -until the next chapter - where your application becomes alive! - -[Previous: \l {Advanced Tutorial 2 - Populating the Game Canvas}] [\l {advtutorial.html}{Advanced Tutorial}] [Next: \l {Advanced Tutorial 4 - Finishing Touches}] - -*/ - diff --git a/doc/src/declarative/advtutorial4.qdoc b/doc/src/declarative/advtutorial4.qdoc deleted file mode 100644 index 059f8bf..0000000 --- a/doc/src/declarative/advtutorial4.qdoc +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page advtutorial4.html -\title Advanced Tutorial 4 - Finishing Touches - -Now we're going to do two things to liven the game up. Animate the blocks and add a web-based high score system. - -If you compare the \c samegame3 directory with \c samegame4, you'll noticed that we've cleaned the directory structure up. -We now have a lot of files, and so they've been split up into folders - the most notable one being a content folder -which we've placed all the QML but the main file. - -\section2 Animated Blocks - -The most vital animations are that the blocks move fluidly around the board. QML has many tools for fluid behavior, -and in this case we're going to use the \l SpringFollow element. By having the script set \c targetX and \c targetY, instead of \c x -and \c y directly, we can set the \c x and \c y of the block to a follow. \l SpringFollow is a property value source, which means -that you can set a property to be one of these elements and it will automatically bind the property to the element's value. -The SpringFollow's value follows another value over time, when the value it is tracking changes the SpringFollow's -value will also change, but it will move smoothly there over time with a spring-like movement (based on the spring -parameters specified). This is shown in the below snippet of code from \c Block.qml: - -\code - property int targetX: 0 - property int targetY: 0 - - x: SpringFollow { source: targetX; spring: 2; damping: 0.2 } - y: SpringFollow { source: targetY; spring: 2; damping: 0.2 } -\endcode - -We also have to change the \c{samegame.js} code, so that wherever it was setting the \c x or \c y it now sets \c targetX and \c targetY -(including when creating the block). This simple change is all you need to get spring moving blocks that no longer teleport -around the board. If you try doing just this though, you'll notice that they now never jump from one point to another, even in -the initialization! This gives an odd effect of having them all slide out of the corner (0,0) on start up. We'd rather that they -fall down from the top in rows. To do this, we disable the \c x follow (but not the \c y follow) and only enable it after we've set -the \c x in the \c createBlock function. The above snippet now becomes: - -\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 1 - -The next-most vital animation is a smooth exit. For this animation, we'll use a \l Behavior element. A Behavior is also a property -value source, and it is much like SpringFollow except that it doesn't model the behavior of a spring. You specify how a Behavior -transitions using the standard animations. As we want the blocks to smoothly fade in and out we'll set a Behavior on the block -image's opacity, like so: - -\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 2 - -Note that the \c{opacity: 0} makes it start out transparent. We could set the opacity in the script file when we create and destroy the blocks, -but instead we use states (as this is useful for the next animation we'll implement). The below snippet is set on the root -element of \c{Block.qml}: -\code - property bool dying: false - states: [ - State{ name: "AliveState"; when: spawned == true && dying == false - PropertyChanges { target: img; opacity: 1 } - }, State{ name: "DeathState"; when: dying == true - PropertyChanges { target: img; opacity: 0 } - } - ] -\endcode - -Now it will automatically fade in, as we set spawned to true already when implementing the block movement animations. -To fade out, we set 'dying' to true instead of setting opacity to 0 when a block is destroyed (in the \c floodFill function). - -The least vital animations are a cool-looking particle effect when they get destroyed. First we create a \l Particles element in -the block, like so: - -\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 3 - -To fully understand this you'll want to look at the Particles element documentation, but it's important to note that emissionRate is set -to zero, so that no particles are emitted normally. -We next extend the 'dying' state, which creates a burst of particles by calling the burst method on the particles element. The code for the states now look -like this: - -\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 4 - -And now the game should be beautifully animated and smooth, with a subtle (or not-so-subtle) animation added for all of the -player's actions. The end result is shown below, with a different set of images to demonstrate basic themeing: - -\image declarative-adv-tutorial4.gif - -The basic theme change there is the result of simply replacing the images. This can be done at run time by setting the source property, so a further advanced feature to try on your own is to add a button which toggles between two different themes. - -\section2 Offline High Scores -Another extension we might want for the game is some way of storing and retrieving high scores. This tutorial contains both online and offline high score storage. - -For better high score data, we want the name and time of the player. The time is obtained in the script fairly simply, but we -have to ask the player for their name. We thus re-use the dialog QML file to pop up a dialog asking for the player's name (and -if they exit this dialog without entering it they have a way to opt out of posting their high score). When the dialog is closed we store the name and high score, using the code below. - -\snippet declarative/tutorials/samegame/samegame4/content/samegame.js 2 - -For offline storage, we use the HTML 5 offline storage JavaScript API to maintain a persistant SQL database unique to this application. This first line in this function calls the function for the web-based high scores, described later, if it has been setup. Next we create an offline storage database for the high scores using openDatabase and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrival, and in the db.transaction call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string. For a more detailed explanation of the offline storage API in QML, consult the global object documentation. - -This is one way of storing and displaying high scores locally, but not the only way. A more complex alternative would have been to create a high score dialog component, and pass the results to it for processing and display (instead of resusing the Dialog). This would allow a more themable dialog that could present the high scores better. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database. - -\section2 Web-based High Scores - -You've seen how to store high scores locally, but it is also easy to integrate a web enabled high score storage into your QML application. This tutorial also shows you how to communicate the high scores to a web server. The implementation we've done is very -simple - the high score data is posted to a php script running on a server somewhere, and that server then stores it and -displays it to visitors. You could request an XML or QML file from that same server, which contained and displayed the scores, -but that's beyond the scope of this tutorial. The php script we've used is available in the examples directory. - -if the player entered their name we can send the data to the web service in the following snippet out of the script file: - -\snippet declarative/tutorials/samegame/samegame4/content/samegame.js 1 - -This is the same \c XMLHttpRequest() as you'll find in browser JavaScript, and can be used in the same way to dynamically get XML -or QML from the web service to display the high scores. We don't worry about the response in this case, we just post the high -score data to the web server. If it had returned a QML file (or a URL to a QML file) you could instantiate it in much the same -way as you did the blocks. - -An alternate way to access and submit web-based data would be to use QML elements designed for this purpose - XmlListModel -makes it very easy to fetch and display XML based data such as RSS in a QML application (see the Flickr demo for an example). - -By following this tutorial you've now ben shown how to write a fully functional application in QML, with the application logic -written in a script file and with both many fluid animations and being web-enabled. Congratulations, you should now be skilled -enough to write entire applications in QML. - -[Previous: \l {Advanced Tutorial 3 - Implementing the Game Logic}] [\l {advtutorial.html}{Advanced Tutorial}] -*/ diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 6a1b2b1..c57b73e 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -73,8 +73,8 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \section1 Getting Started: \list \o \l {Introduction to the QML language} -\o \l {Tutorial}{Tutorial: 'Hello World'} -\o \l {advtutorial.html}{Tutorial: 'Same Game'} +\o \l {QML Tutorial}{Tutorial: 'Hello World'} +\o \l {QML Advanced Tutorial}{Tutorial: 'Same Game'} \o \l {QML Examples and Walkthroughs} \o \l {Using QML in C++ Applications} \endlist diff --git a/doc/src/declarative/examples.qdoc b/doc/src/declarative/examples.qdoc index 46cac07..6048467 100644 --- a/doc/src/declarative/examples.qdoc +++ b/doc/src/declarative/examples.qdoc @@ -80,7 +80,7 @@ These will be documented, and demonstrate how to achieve various things in QML. \o \l{qmlexampletoggleswitch.html}{Toggle Switch} \o \image switch-example.gif \row - \o \l{Advanced Tutorial}{SameGame} + \o \l{QML Advanced Tutorial}{SameGame} \o \image declarative-adv-tutorial4.gif \endtable diff --git a/doc/src/declarative/qmlreference.qdoc b/doc/src/declarative/qmlreference.qdoc index f52ff41..c6ccbe0 100644 --- a/doc/src/declarative/qmlreference.qdoc +++ b/doc/src/declarative/qmlreference.qdoc @@ -65,8 +65,8 @@ Getting Started: \list \o \l {Introduction to the QML language} - \o \l {tutorial}{Tutorial: 'Hello World'} - \o \l {advtutorial.html}{Advanced Tutorial: 'Same Game'} + \o \l {QML Tutorial}{Tutorial: 'Hello World'} + \o \l {QML Advanced Tutorial}{Advanced Tutorial: 'Same Game'} \o \l {QML Examples and Walkthroughs} \endlist diff --git a/doc/src/declarative/tutorial.qdoc b/doc/src/declarative/tutorial.qdoc index 54b6610..e136ada 100644 --- a/doc/src/declarative/tutorial.qdoc +++ b/doc/src/declarative/tutorial.qdoc @@ -40,11 +40,13 @@ ****************************************************************************/ /*! -\page tutorial.html -\title Tutorial +\page qml-tutorial.html +\title QML Tutorial +\brief An introduction to the basic concepts and features of QML. +\nextpage QML Tutorial 1 - Basic Types -This tutorial gives an introduction to QML. It doesn't cover everything; the emphasis is on teaching the key principles, -and features are introduced as needed. +This tutorial gives an introduction to QML, the mark up language for Qt Quick. It doesn't cover everything; +the emphasis is on teaching the key principles, and features are introduced as needed. Through the different steps of this tutorial we will learn about QML basic types, we will create our own QML component with properties and signals, and we will create a simple animation with the help of states and transitions. @@ -56,9 +58,182 @@ The tutorial's source code is located in the $QTDIR/examples/declarative/tutoria Tutorial chapters: \list -\o \l {Tutorial 1 - Basic Types} -\o \l {Tutorial 2 - QML Component} -\o \l {Tutorial 3 - States and Transitions} +\o \l {QML Tutorial 1 - Basic Types} +\o \l {QML Tutorial 2 - QML Component} +\o \l {QML Tutorial 3 - States and Transitions} \endlist */ + +/*! +\page qml-tutorial1.html +\title QML Tutorial 1 - Basic Types +\contentspage QML Tutorial +\previouspage QML Tutorial +\nextpage QML Tutorial 2 - QML Component + +This first program is a very simple "Hello world" example that introduces some basic QML concepts. +The picture below is a screenshot of this program. + +\image declarative-tutorial1.png + +Here is the QML code for the application: + +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 0 + +\section1 Walkthrough + +\section2 Import + +First, we need to import the types that we need for this example. Most QML files will import the built-in QML +types (like \l{Rectangle}, \l{Image}, ...) that come with Qt with: + +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 3 + +\section2 Rectangle element + +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 1 + +We declare a root element of type \l{Rectangle}. It is one of the basic building blocks you can use to create an application in QML. +We give it an \c{id} to be able to refer to it later. In this case, we call it \e page. +We also set the \c width, \c height and \c color properties. +The \l{Rectangle} element contains many other properties (such as \c x and \c y), but these are left at their default values. + +\section2 Text element + +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 2 + +We add a \l Text element as a child of our root element that will display the text 'Hello world!'. + +The \c y property is used to position the text vertically at 30 pixels from the top of its parent. + +The \c font.pointSize and \c font.bold properties are related to fonts and use the \l{dot properties}{dot notation}. + +The \c anchors.horizontalCenter property refers to the horizontal center of an element. +In this case, we specify that our text element should be horizontally centered in the \e page element (see \l{anchor-layout}{Anchor-based Layout}). + +\section2 Viewing the example + +To view what you have created, run the qmlviewer (located in the \c bin directory) with your filename as the first argument. +For example, to run the provided completed Tutorial 1 example from the install location, you would type: + +\code +bin/qmlviewer $QTDIR/examples/declarative/tutorials/helloworld/tutorial1.qml +\endcode +*/ + +/*! +\page qml-tutorial2.html +\title QML Tutorial 2 - QML Component +\contentspage QML Tutorial +\previouspage QML Tutorial 1 - Basic Types +\nextpage QML Tutorial 3 - States and Transitions + +This chapter adds a color picker to change the color of the text. + +\image declarative-tutorial2.png + +Our color picker is made of six cells with different colors. +To avoid writing the same code multiple times, we first create a new \c Cell component. +A component provides a way of defining a new type that we can re-use in other QML files. +A QML component is like a black-box and interacts with the outside world through properties, signals and slots and is generally +defined in its own QML file (for more details, see \l {Defining new Components}). +The component's filename must always start with a capital letter. + +Here is the QML code for \c Cell.qml: + +\snippet examples/declarative/tutorials/helloworld/Cell.qml 0 + +\section1 Walkthrough + +\section2 The Cell Component + +\snippet examples/declarative/tutorials/helloworld/Cell.qml 1 + +The root element of our component is an \l Item with the \c id \e container. +An \l Item is the most basic visual element in QML and is often used as a container for other elements. + +\snippet examples/declarative/tutorials/helloworld/Cell.qml 4 + +We declare a \c color property. This property is accessible from \e outside our component, this allows us +to instantiate the cells with different colors. +This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{intro-properties}{Properties}). + +\snippet examples/declarative/tutorials/helloworld/Cell.qml 5 + +We want our component to also have a signal that we call \e clicked with a \e color parameter. +We will use this signal to change the color of the text in the main QML file later. + +\snippet examples/declarative/tutorials/helloworld/Cell.qml 2 + +Our cell component is basically a colored rectangle with the \c id \e rectangle. + +The \c anchors.fill property is a convenient way to set the size of an element. +In this case the rectangle will have the same size as its parent (see \l{anchor-layout}{Anchor-based Layout}). + +\snippet examples/declarative/tutorials/helloworld/Cell.qml 3 + +In order to change the color of the text when clicking on a cell, we create a \l MouseRegion element with +the same size as its parent. + +A \l MouseRegion defines a signal called \e clicked. +When this signal is triggered we want to emit our own \e clicked signal with the color as parameter. + +\section2 The main QML file + +In our main QML file, we use our \c Cell component to create the color picker: + +\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 0 + +We create the color picker by putting 6 cells with different colors in a grid. + +\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 1 + +When the \e clicked signal of our cell is triggered, we want to set the color of the text to the color passed as a parameter. +We can react to any signal of our component through a property of the name \e 'onSignalName' (see \l{Signal Handlers}). +*/ + +/*! +\page qml-tutorial3.html +\title QML Tutorial 3 - States and Transitions +\contentspage QML Tutorial +\previouspage QML Tutorial 2 - QML Component + +In this chapter, we make this example a little bit more dynamic by introducing states and transitions. + +We want our text to move to the bottom of the screen, rotate and become red when clicked. + +\image declarative-tutorial3_animation.gif + +Here is the QML code: + +\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 0 + +\section1 Walkthrough + +\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 2 + +First, we create a new \e down state for our text element. +This state will be activated when the \l MouseRegion is pressed, and deactivated when it is released. + +The \e down state includes a set of property changes from our implicit \e {default state} +(the items as they were initially defined in the QML). +Specifically, we set the \c y property of the text to \c 160, the rotation to \c 180 and the \c color to red. + +\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 3 + +Because we don't want the text to appear at the bottom instantly but rather move smoothly, +we add a transition between our two states. + +\c from and \c to define the states between which the transition will run. +In this case, we want a transition from the default state to our \e down state. + +Because we want the same transition to be run in reverse when changing back from the \e down state to the default state, +we set \c reversible to \c true. +This is equivalent to writing the two transitions separately. + +The \l ParallelAnimation element makes sure that the two types of animations (number and color) start at the same time. +We could also run them one after the other by using \l SequentialAnimation instead. + +For more details on states and transitions, see \l {QML States}. +*/ diff --git a/doc/src/declarative/tutorial1.qdoc b/doc/src/declarative/tutorial1.qdoc deleted file mode 100644 index b89c74a..0000000 --- a/doc/src/declarative/tutorial1.qdoc +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page tutorial1.html -\title Tutorial 1 - Basic Types - -This first program is a very simple "Hello world" example that introduces some basic QML concepts. -The picture below is a screenshot of this program. - -\image declarative-tutorial1.png - -Here is the QML code for the application: - -\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 0 - -\section1 Walkthrough - -\section2 Import - -First, we need to import the types that we need for this example. Most QML files will import the built-in QML -types (like \l{Rectangle}, \l{Image}, ...) that come with Qt with: - -\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 3 - -\section2 Rectangle element - -\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 1 - -We declare a root element of type \l{Rectangle}. It is one of the basic building blocks you can use to create an application in QML. -We give it an \c{id} to be able to refer to it later. In this case, we call it \e page. -We also set the \c width, \c height and \c color properties. -The \l{Rectangle} element contains many other properties (such as \c x and \c y), but these are left at their default values. - -\section2 Text element - -\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 2 - -We add a \l Text element as a child of our root element that will display the text 'Hello world!'. - -The \c y property is used to position the text vertically at 30 pixels from the top of its parent. - -The \c font.pointSize and \c font.bold properties are related to fonts and use the \l{dot properties}{dot notation}. - -The \c anchors.horizontalCenter property refers to the horizontal center of an element. -In this case, we specify that our text element should be horizontally centered in the \e page element (see \l{anchor-layout}{Anchor-based Layout}). - -\section2 Viewing the example - -To view what you have created, run the qmlviewer (located in the \c bin directory) with your filename as the first argument. -For example, to run the provided completed Tutorial 1 example from the install location, you would type: - -\code -bin/qmlviewer $QTDIR/examples/declarative/tutorials/helloworld/tutorial1.qml -\endcode - -[\l {Tutorial}] [Next: \l {Tutorial 2 - QML Component}] - -*/ diff --git a/doc/src/declarative/tutorial2.qdoc b/doc/src/declarative/tutorial2.qdoc deleted file mode 100644 index 3e92e37..0000000 --- a/doc/src/declarative/tutorial2.qdoc +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page tutorial2.html -\title Tutorial 2 - QML Component - -This chapter adds a color picker to change the color of the text. - -\image declarative-tutorial2.png - -Our color picker is made of six cells with different colors. -To avoid writing the same code multiple times, we first create a new \c Cell component. -A component provides a way of defining a new type that we can re-use in other QML files. -A QML component is like a black-box and interacts with the outside world through properties, signals and slots and is generally -defined in its own QML file (for more details, see \l {Defining new Components}). -The component's filename must always start with a capital letter. - -Here is the QML code for \c Cell.qml: - -\snippet examples/declarative/tutorials/helloworld/Cell.qml 0 - -\section1 Walkthrough - -\section2 The Cell Component - -\snippet examples/declarative/tutorials/helloworld/Cell.qml 1 - -The root element of our component is an \l Item with the \c id \e container. -An \l Item is the most basic visual element in QML and is often used as a container for other elements. - -\snippet examples/declarative/tutorials/helloworld/Cell.qml 4 - -We declare a \c color property. This property is accessible from \e outside our component, this allows us -to instantiate the cells with different colors. -This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{intro-properties}{Properties}). - -\snippet examples/declarative/tutorials/helloworld/Cell.qml 5 - -We want our component to also have a signal that we call \e clicked with a \e color parameter. -We will use this signal to change the color of the text in the main QML file later. - -\snippet examples/declarative/tutorials/helloworld/Cell.qml 2 - -Our cell component is basically a colored rectangle with the \c id \e rectangle. - -The \c anchors.fill property is a convenient way to set the size of an element. -In this case the rectangle will have the same size as its parent (see \l{anchor-layout}{Anchor-based Layout}). - -\snippet examples/declarative/tutorials/helloworld/Cell.qml 3 - -In order to change the color of the text when clicking on a cell, we create a \l MouseRegion element with -the same size as its parent. - -A \l MouseRegion defines a signal called \e clicked. -When this signal is triggered we want to emit our own \e clicked signal with the color as parameter. - -\section2 The main QML file - -In our main QML file, we use our \c Cell component to create the color picker: - -\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 0 - -We create the color picker by putting 6 cells with different colors in a grid. - -\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 1 - -When the \e clicked signal of our cell is triggered, we want to set the color of the text to the color passed as a parameter. -We can react to any signal of our component through a property of the name \e 'onSignalName' (see \l{Signal Handlers}). - -[Previous: \l {Tutorial 1 - Basic Types}] [Next: \l {Tutorial 3 - States and Transitions}] - -*/ - diff --git a/doc/src/declarative/tutorial3.qdoc b/doc/src/declarative/tutorial3.qdoc deleted file mode 100644 index e4d7995..0000000 --- a/doc/src/declarative/tutorial3.qdoc +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -/*! -\page tutorial3.html -\title Tutorial 3 - States and Transitions - -In this chapter, we make this example a little bit more dynamic by introducing states and transitions. - -We want our text to move to the bottom of the screen, rotate and become red when clicked. - -\image declarative-tutorial3_animation.gif - -Here is the QML code: - -\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 0 - -\section1 Walkthrough - -\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 2 - -First, we create a new \e down state for our text element. -This state will be activated when the \l MouseRegion is pressed, and deactivated when it is released. - -The \e down state includes a set of property changes from our implicit \e {default state} -(the items as they were initially defined in the QML). -Specifically, we set the \c y property of the text to \c 160, the rotation to \c 180 and the \c color to red. - -\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 3 - -Because we don't want the text to appear at the bottom instantly but rather move smoothly, -we add a transition between our two states. - -\c from and \c to define the states between which the transition will run. -In this case, we want a transition from the default state to our \e down state. - -Because we want the same transition to be run in reverse when changing back from the \e down state to the default state, -we set \c reversible to \c true. -This is equivalent to writing the two transitions separately. - -The \l ParallelAnimation element makes sure that the two types of animations (number and color) start at the same time. -We could also run them one after the other by using \l SequentialAnimation instead. - -For more details on states and transitions, see \l {QML States}. - -[Previous: \l {Tutorial 2 - QML Component}] [\l {Tutorial}] - -*/ -- cgit v0.12 From d98a1d569533891bb6def33c3233f1ebaf82d9fa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 19 Feb 2010 16:17:26 +0100 Subject: Fix compilation on GNU/Hurd (SA_SIGINFO isn't defined) Task-number: QTBUG-7805 Patch-by: Pino Toscano Reviewed-by: Trust Me --- src/testlib/qtestcase.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 40daecb..22b59ae 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1531,7 +1531,11 @@ FatalSignalHandler::FatalSignalHandler() #ifndef Q_WS_QWS // Don't overwrite any non-default handlers // however, we need to replace the default QWS handlers - if (oldact.sa_flags & SA_SIGINFO || oldact.sa_handler != SIG_DFL) { + if ( +#ifdef SA_SIGINFO + oldact.sa_flags & SA_SIGINFO || +#endif + oldact.sa_handler != SIG_DFL) { sigaction(fatalSignals[i], &oldact, 0); } else #endif -- cgit v0.12 From ba9c21f7a1398ddcdeee6f010b1477d79f5bb8ce Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 19 Feb 2010 16:11:19 +0100 Subject: Cocoa: calling QEventLoop::exec from mouse up causes problem If one create e.g. a modal dialog from a mouse up event handler, we qt_button_down global variable was pointing to a widget before the handler returned. This meant that you could not push another button in the window, since the qt_button_down would grab the mouse. This patch clears qt_button_down before sending mouse up events. Reviewed-by: denis --- src/gui/kernel/qt_cocoa_helpers_mac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index b400d25..9702829 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -983,6 +983,7 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev button = Qt::RightButton; [theView qt_setLeftButtonIsRightButton: false]; } + qt_button_down = 0; break; } [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint; -- cgit v0.12 From a3d3f72bf571d46fc03c62b5aae51f5cc94d6999 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Feb 2010 11:13:29 +0100 Subject: Fix compilation on recent Linux systems: getpid(2) is in unistd.h. Newer Linux systems (glibc 2.10, gcc 4.4) are much better at not leaking symbols, so you have to include the proper headers. --- src/multimedia/qml/qsoundeffect_pulse_p.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.cpp b/src/multimedia/qml/qsoundeffect_pulse_p.cpp index b1e5982..de02dac 100644 --- a/src/multimedia/qml/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/qml/qsoundeffect_pulse_p.cpp @@ -67,6 +67,8 @@ #include #endif +#include + // Less than ideal #define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16) -- cgit v0.12 From 1642c39cdc7f21cf5f183567197a19df2ab8afde Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Feb 2010 11:26:02 +0100 Subject: Fix compilation: qmlviewer cannot use symbols exported with Q_AUTOTEST_EXPORT in production builds --- src/gui/graphicsview/qgraphicsview_p.h | 2 +- src/gui/widgets/qabstractscrollarea_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 9d3edcb..729837a 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate +class Q_GUI_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QGraphicsView) public: diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 7c72859..9a0d66f 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QScrollBar; class QAbstractScrollAreaScrollBarContainer; -class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate +class Q_GUI_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate { Q_DECLARE_PUBLIC(QAbstractScrollArea) -- cgit v0.12 From 4b82d6f99f7c231cbba1dd5e09ecb09d2218c8bc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Feb 2010 11:28:28 +0100 Subject: WinCE doesn't have sys/types.h --- src/3rdparty/libpng/pngconf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 9eec6d3..5d202db 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -330,7 +330,7 @@ #endif /* Enough people need this for various reasons to include it here */ -#if !defined(MACOS) && !defined(RISCOS) +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) # include #endif -- cgit v0.12 From 871e5b4205f08849d089454721c4e27b6b53b51e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Feb 2010 11:31:39 +0100 Subject: Fix compilation on HP-UXi: m_volume is a #define --- src/multimedia/qml/qsoundeffect.cpp | 10 +++++----- src/multimedia/qml/qsoundeffect_p.h | 2 +- src/multimedia/qml/qsoundeffect_pulse_p.cpp | 16 ++++++++-------- src/multimedia/qml/qsoundeffect_pulse_p.h | 2 +- src/multimedia/qml/qsoundeffect_qmedia_p.cpp | 8 ++++---- src/multimedia/qml/qsoundeffect_qmedia_p.h | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/multimedia/qml/qsoundeffect.cpp b/src/multimedia/qml/qsoundeffect.cpp index 1a67414..1f2c801 100644 --- a/src/multimedia/qml/qsoundeffect.cpp +++ b/src/multimedia/qml/qsoundeffect.cpp @@ -139,7 +139,7 @@ QSoundEffect::QSoundEffect(QObject *parent) : QObject(parent), m_loopCount(1), - m_volume(100), + m_vol(100), m_muted(false), m_runningCount(0) { @@ -165,7 +165,7 @@ void QSoundEffect::setSource(const QUrl &url) if (d != 0 && d->media().canonicalUrl() == url) return; - d->setVolume(m_volume); + d->setVolume(m_vol); d->setMuted(m_muted); d->setMedia(url); @@ -191,15 +191,15 @@ void QSoundEffect::setLoopCount(int loopCount) int QSoundEffect::volume() const { - return d != 0 ? d->volume() : m_volume; + return d != 0 ? d->volume() : m_vol; } void QSoundEffect::setVolume(int volume) { - if (m_volume == volume) + if (m_vol == volume) return; - m_volume = volume; + m_vol = volume; if (d != 0) d->setVolume(volume); else diff --git a/src/multimedia/qml/qsoundeffect_p.h b/src/multimedia/qml/qsoundeffect_p.h index 2610a69..5b978e5 100644 --- a/src/multimedia/qml/qsoundeffect_p.h +++ b/src/multimedia/qml/qsoundeffect_p.h @@ -109,7 +109,7 @@ private: Q_DISABLE_COPY(QSoundEffect) int m_loopCount; - int m_volume; + int m_vol; bool m_muted; int m_runningCount; diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.cpp b/src/multimedia/qml/qsoundeffect_pulse_p.cpp index de02dac..36fd69d 100644 --- a/src/multimedia/qml/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/qml/qsoundeffect_pulse_p.cpp @@ -130,13 +130,13 @@ public: int volume() { - return m_volume; + return m_vol; } private: void prepare() { - m_volume = 100; + m_vol = 100; m_mainLoop = pa_threaded_mainloop_new(); if (m_mainLoop == 0) { @@ -217,13 +217,13 @@ private: const unsigned str_length = 256; char str[str_length]; pa_cvolume_snprint(str, str_length, &info->volume); - self->m_volume = QString(str).replace(" ","").replace("%","").mid(2).toInt(); + self->m_vol = QString(str).replace(" ","").replace("%","").mid(2).toInt(); } } } #endif - int m_volume; + int m_vol; bool m_prepared; pa_context *m_context; pa_threaded_mainloop *m_mainLoop; @@ -238,7 +238,7 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QObject(parent), m_muted(false), m_playQueued(false), - m_volume(100), + m_vol(100), m_duration(0), m_dataUploaded(0), m_state(QMediaPlayer::StoppedState), @@ -262,7 +262,7 @@ qint64 QSoundEffectPrivate::duration() const int QSoundEffectPrivate::volume() const { - return m_volume; + return m_vol; } bool QSoundEffectPrivate::isMuted() const @@ -300,7 +300,7 @@ void QSoundEffectPrivate::play() daemon()->lock(); #if(Q_WS_MAEMO_5) - m_vol = PA_VOLUME_NORM/100*((daemon()->volume()+m_volume)/2); + m_vol = PA_VOLUME_NORM/100*((daemon()->volume()+m_vol)/2); #endif pa_operation_unref( pa_context_play_sample(daemon()->context(), @@ -324,7 +324,7 @@ void QSoundEffectPrivate::stop() void QSoundEffectPrivate::setVolume(int volume) { - m_volume = volume; + m_vol = volume; } void QSoundEffectPrivate::setMuted(bool muted) diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.h b/src/multimedia/qml/qsoundeffect_pulse_p.h index 58a05d2..247f8a3 100644 --- a/src/multimedia/qml/qsoundeffect_pulse_p.h +++ b/src/multimedia/qml/qsoundeffect_pulse_p.h @@ -117,7 +117,7 @@ private: bool m_muted; bool m_playQueued; - int m_volume; + int m_vol; int m_duration; int m_dataUploaded; QTime m_playbackTime; diff --git a/src/multimedia/qml/qsoundeffect_qmedia_p.cpp b/src/multimedia/qml/qsoundeffect_qmedia_p.cpp index e5ac0d3..886380a 100644 --- a/src/multimedia/qml/qsoundeffect_qmedia_p.cpp +++ b/src/multimedia/qml/qsoundeffect_qmedia_p.cpp @@ -62,7 +62,7 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QObject(parent), m_muted(false), - m_volume(100), + m_vol(100), m_player(0) { } @@ -83,7 +83,7 @@ int QSoundEffectPrivate::volume() const { if (m_player) return m_player->volume(); - return m_volume; + return m_vol; } bool QSoundEffectPrivate::isMuted() const @@ -128,7 +128,7 @@ void QSoundEffectPrivate::stop() void QSoundEffectPrivate::setVolume(int volume) { - m_volume = volume; + m_vol = volume; if (m_player) m_player->setVolume(volume); @@ -149,7 +149,7 @@ void QSoundEffectPrivate::setMedia(const QMediaContent &media) if (m_player == 0) { m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency); - m_player->setVolume(m_volume); + m_player->setVolume(m_vol); m_player->setMuted(m_muted); connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int))); diff --git a/src/multimedia/qml/qsoundeffect_qmedia_p.h b/src/multimedia/qml/qsoundeffect_qmedia_p.h index e17d720..8267f79 100644 --- a/src/multimedia/qml/qsoundeffect_qmedia_p.h +++ b/src/multimedia/qml/qsoundeffect_qmedia_p.h @@ -98,7 +98,7 @@ Q_SIGNALS: private: bool m_muted; - int m_volume; + int m_vol; QMediaPlayer *m_player; }; -- cgit v0.12