diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-04-17 16:35:19 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-04-17 22:32:42 +0200 |
commit | 7d3a56f3cf717a06823c33b031ea4f590e14002d (patch) | |
tree | b5d2845e8353ba2de3028a9f32749ca622e115da /src | |
parent | f92c3aecd08eef468f9a47f2e970f22beecc8216 (diff) | |
parent | e5f45d9b57bb0542ec47e5a8a4e57388b6d59d35 (diff) |
Merge remote-tracking branch 'origin/api_changes'
Change-Id: I39905acde16ba6bb0ba39401cb73082a73dd9167
Diffstat (limited to 'src')
66 files changed, 3222 insertions, 1733 deletions
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index 4938347b9b..d8997fd587 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -271,10 +271,8 @@ void QQmlEngineDebugService::buildObjectDump(QDataStream &message, prop.value = expr->expression(); QObject *scope = expr->scopeObject(); if (scope) { - QString sig = QString::fromLatin1(scope->metaObject()->method(signalHandler->index()).signature()); - int lparen = sig.indexOf(QLatin1Char('(')); - if (lparen >= 0) { - QString methodName = sig.mid(0, lparen); + QString methodName = QString::fromLatin1(scope->metaObject()->method(signalHandler->index()).name()); + if (!methodName.isEmpty()) { prop.name = QLatin1String("on") + methodName[0].toUpper() + methodName.mid(1); } diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index 88a965e6c1..8662abb52e 100644 --- a/src/qml/debugger/qqmlprofilerservice_p.h +++ b/src/qml/debugger/qqmlprofilerservice_p.h @@ -209,7 +209,7 @@ struct QQmlHandlingSignalProfiler { QQmlProfilerService *service = QQmlProfilerService::instance; service->startRange(QQmlProfilerService::HandlingSignal); service->rangeData(QQmlProfilerService::HandlingSignal, - QLatin1String(signal.signature()) + QLatin1String(": ") + QString::fromLatin1(signal.methodSignature()) + QLatin1String(": ") + expression->expression()); service->rangeLocation(QQmlProfilerService::HandlingSignal, expression->sourceFile(), expression->lineNumber(), diff --git a/src/qml/qml.pro b/src/qml/qml.pro index 0bbfc9ff74..acafb9f6a3 100644 --- a/src/qml/qml.pro +++ b/src/qml/qml.pro @@ -6,7 +6,7 @@ QPRO_PWD = $$PWD CONFIG += module MODULE_PRI += ../../modules/qt_qml.pri -QT = core-private gui gui-private network v8-private +QT = core-private network v8-private DEFINES += QT_BUILD_QML_LIB QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES diff --git a/src/qml/qml/ftw/qfastmetabuilder.cpp b/src/qml/qml/ftw/qfastmetabuilder.cpp index 08ea76b37e..9d956054d9 100644 --- a/src/qml/qml/ftw/qfastmetabuilder.cpp +++ b/src/qml/qml/ftw/qfastmetabuilder.cpp @@ -79,7 +79,8 @@ static inline const QFastMetaBuilderHeader *header(const QByteArray &data) { return reinterpret_cast<const QFastMetaBuilderHeader*>(data.constData()); } QFastMetaBuilder::QFastMetaBuilder() -: m_zeroPtr(0), m_stringData(0), m_stringDataLength(0), m_stringDataAllocated(0) + : m_stringData(0), m_stringCount(0), m_stringDataLength(0), + m_stringCountAllocated(0), m_stringCountLoaded(0) { } @@ -89,7 +90,8 @@ QFastMetaBuilder::~QFastMetaBuilder() QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength, int propertyCount, int methodCount, - int signalCount, int classInfoCount) + int signalCount, int classInfoCount, + int paramDataSize, int *paramIndex) { Q_ASSERT(m_data.isEmpty()); Q_ASSERT(classNameLength > 0); @@ -97,20 +99,29 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength, Q_ASSERT(methodCount >= 0); Q_ASSERT(signalCount >= 0); Q_ASSERT(classInfoCount >= 0); + Q_ASSERT(paramDataSize >= 0); + Q_ASSERT((paramIndex != 0) || (methodCount + signalCount == 0)); int fieldCount = FMBHEADER_FIELD_COUNT + HEADER_FIELD_COUNT + propertyCount * (PROPERTY_FIELD_COUNT + PROPERTY_NOTIFY_FIELD_COUNT) + methodCount * (METHOD_FIELD_COUNT) + signalCount * (METHOD_FIELD_COUNT) + + paramDataSize + classInfoCount * CLASSINFO_FIELD_COUNT; + // Ensure stringdata alignment (void*) + fieldCount += fieldCount % (sizeof(void*) / sizeof(uint)); - m_data.resize(fieldCount * sizeof(uint) + classNameLength + 1); - m_stringData = m_data.data() + m_data.size() - classNameLength - 1; + m_stringCount = 2; // class name and zero string m_stringDataLength = classNameLength + 1; - m_stringDataAllocated = classNameLength + 1; - m_stringData[classNameLength] = 0; - m_zeroPtr = classNameLength; + m_data.resize(fieldCount * sizeof(uint) + m_stringCount * sizeof(QByteArrayData) + m_stringDataLength); + m_stringCountAllocated = m_stringCount; + m_stringData = reinterpret_cast<QByteArrayData *>(m_data.data() + fieldCount * sizeof(uint)); + + m_zeroString._b = this; + m_zeroString._i = 1; + m_zeroString._o = classNameLength; + m_zeroString._l = 0; header(m_data)->fieldCount = fieldCount; @@ -118,7 +129,7 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength, int dataIndex = HEADER_FIELD_COUNT; - p->revision = 6; + p->revision = 7; p->className = 0; // Class infos @@ -135,6 +146,8 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength, if (p->methodCount) { p->methodData = dataIndex; dataIndex += p->methodCount * METHOD_FIELD_COUNT; + *paramIndex = dataIndex; + dataIndex += paramDataSize; } else { p->methodData = 0; } @@ -160,6 +173,7 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength, StringRef className; className._b = this; + className._i = 0; className._o = 0; className._l = classNameLength; return className; @@ -169,12 +183,16 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength, QFastMetaBuilder::StringRef QFastMetaBuilder::newString(int length) { Q_ASSERT(length > 0); + Q_ASSERT_X(m_stringCountLoaded == 0, Q_FUNC_INFO, + "All strings must be created before string loading begins"); StringRef sr; sr._b = this; + sr._i = m_stringCount; sr._o = m_stringDataLength; sr._l = length; + ++m_stringCount; m_stringDataLength += length + 1 /* for null terminator */; return sr; @@ -190,47 +208,24 @@ void QFastMetaBuilder::setClassInfo(int index, const StringRef &key, const Strin uint *ptr = fieldPointer(m_data) + p->classInfoData + index * CLASSINFO_FIELD_COUNT; // classinfo: key, value - ptr[0] = key.offset(); ptr[1] = value.offset(); + ptr[0] = key.index(); ptr[1] = value.index(); } -void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type, - QMetaType::Type mtype, PropertyFlag flags, int notifySignal) +void QFastMetaBuilder::setProperty(int index, const StringRef &name, int type, + PropertyFlag flags, int notifySignal) { Q_ASSERT(!m_data.isEmpty()); Q_ASSERT(!name.isEmpty()); - Q_ASSERT(!type.isEmpty()); - - QMetaObjectPrivate *p = priv(m_data); - Q_ASSERT(index < p->propertyCount); - - uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT; - // properties: name, type, flags - ptr[0] = name.offset(); - ptr[1] = type.offset(); - if (notifySignal == -1) { - ptr[2] = mtype << 24; - ptr[2] |= flags | Scriptable | Readable; - *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0; - } else { - ptr[2] = mtype << 24; - ptr[2] |= flags | Scriptable | Readable | Notify; - *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = notifySignal; - } -} - -void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type, - QFastMetaBuilder::PropertyFlag flags, int notifySignal) -{ - Q_ASSERT(!m_data.isEmpty()); - Q_ASSERT(!name.isEmpty() && !type.isEmpty()); + Q_ASSERT(type != 0); + Q_ASSERT(QMetaType::isRegistered(type)); QMetaObjectPrivate *p = priv(m_data); Q_ASSERT(index < p->propertyCount); uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT; // properties: name, type, flags - ptr[0] = name.offset(); - ptr[1] = type.offset(); + ptr[0] = name.index(); + ptr[1] = type; if (notifySignal == -1) { ptr[2] = flags | Scriptable | Readable; *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0; @@ -240,42 +235,72 @@ void QFastMetaBuilder::setProperty(int index, const StringRef &name, const Strin } } -void QFastMetaBuilder::setSignal(int index, const StringRef &signature, - const StringRef ¶meterNames, - const StringRef &type) +void QFastMetaBuilder::setSignal(int index, const StringRef &name, + int paramIndex, int argc, const int *types, + const StringRef *parameterNames, + QMetaType::Type type) { Q_ASSERT(!m_data.isEmpty()); - Q_ASSERT(!signature.isEmpty()); + Q_ASSERT(!name.isEmpty()); + Q_ASSERT(QMetaType::isRegistered(type)); QMetaObjectPrivate *p = priv(m_data); int mindex = metaObjectIndexForSignal(index); uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT; - // methods: signature, parameters, type, tag, flags - ptr[0] = signature.offset(); - ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset(); - ptr[2] = type.isEmpty()?m_zeroPtr:type.offset(); - ptr[3] = m_zeroPtr; + // methods: name, arc, parameters, tag, flags + ptr[0] = name.index(); + ptr[1] = argc; + ptr[2] = paramIndex; + ptr[3] = m_zeroString.index(); ptr[4] = AccessProtected | MethodSignal; + + uint *paramPtr = fieldPointer(m_data) + paramIndex; + paramPtr[0] = type; + if (argc) { + Q_ASSERT(types != 0); + Q_ASSERT(parameterNames != 0); + for (int i = 0; i < argc; ++i) { + Q_ASSERT(types[i] != 0); + Q_ASSERT(QMetaType::isRegistered(types[i])); + paramPtr[1+i] = types[i]; + paramPtr[1+argc+i] = parameterNames[i].index(); + } + } } -void QFastMetaBuilder::setMethod(int index, const StringRef &signature, - const StringRef ¶meterNames, - const StringRef &type) +void QFastMetaBuilder::setMethod(int index, const StringRef &name, + int paramIndex, int argc, const int *types, + const StringRef *parameterNames, + QMetaType::Type type) { Q_ASSERT(!m_data.isEmpty()); - Q_ASSERT(!signature.isEmpty()); + Q_ASSERT(!name.isEmpty()); + Q_ASSERT(QMetaType::isRegistered(type)); QMetaObjectPrivate *p = priv(m_data); int mindex = metaObjectIndexForMethod(index); uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT; - // methods: signature, parameters, type, tag, flags - ptr[0] = signature.offset(); - ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset(); - ptr[2] = type.isEmpty()?m_zeroPtr:type.offset(); - ptr[3] = m_zeroPtr; + // methods: name, arc, parameters, tag, flags + ptr[0] = name.index(); + ptr[1] = argc; + ptr[2] = paramIndex; + ptr[3] = m_zeroString.index(); ptr[4] = AccessProtected | MethodSlot; + + uint *paramPtr = fieldPointer(m_data) + paramIndex; + paramPtr[0] = type; + if (argc) { + Q_ASSERT(types != 0); + Q_ASSERT(parameterNames != 0); + for (int i = 0; i < argc; ++i) { + Q_ASSERT(types[i] != 0); + Q_ASSERT(QMetaType::isRegistered(types[i])); + paramPtr[1+i] = types[i]; + paramPtr[1+argc+i] = parameterNames[i].index(); + } + } } int QFastMetaBuilder::metaObjectIndexForSignal(int index) const @@ -296,17 +321,19 @@ int QFastMetaBuilder::metaObjectIndexForMethod(int index) const void QFastMetaBuilder::allocateStringData() { - if (m_stringDataAllocated < m_stringDataLength) { - m_data.resize(m_data.size() + m_stringDataLength - m_stringDataAllocated); - m_stringDataAllocated = m_stringDataLength; - m_stringData = m_data.data() + header(m_data)->fieldCount * sizeof(uint); + if (m_stringCountAllocated < m_stringCount) { + m_data.resize(header(m_data)->fieldCount * sizeof(uint) + + m_stringCount * sizeof(QByteArrayData) + m_stringDataLength); + m_stringCountAllocated = m_stringCount; + char *rawStringData = m_data.data() + header(m_data)->fieldCount * sizeof(uint); + m_stringData = reinterpret_cast<QByteArrayData *>(rawStringData); } } void QFastMetaBuilder::fromData(QMetaObject *output, const QMetaObject *parent, const QByteArray &data) { output->d.superdata = parent; - output->d.stringdata = data.constData() + header(data)->fieldCount * sizeof(uint); + output->d.stringdata = reinterpret_cast<const QByteArrayData *>(data.constData() + header(data)->fieldCount * sizeof(uint)); output->d.data = fieldPointer(data); output->d.extradata = 0; } diff --git a/src/qml/qml/ftw/qfastmetabuilder_p.h b/src/qml/qml/ftw/qfastmetabuilder_p.h index c1f6a3de5c..16f7b6e749 100644 --- a/src/qml/qml/ftw/qfastmetabuilder_p.h +++ b/src/qml/qml/ftw/qfastmetabuilder_p.h @@ -80,13 +80,15 @@ public: inline bool isEmpty() const; inline QFastMetaBuilder *builder() const; - inline int offset() const; + inline int index() const; inline char *data(); inline int length() const; + inline void loadByteArrayData(); private: friend class QFastMetaBuilder; QFastMetaBuilder *_b; + int _i; int _o; int _l; }; @@ -95,7 +97,8 @@ public: // Returns class name StringRef init(int classNameLength, int propertyCount, int methodCount, - int signalCount, int classInfoCount); + int signalCount, int classInfoCount, + int paramDataSize, int *paramIndex); void setClassInfo(int index, const StringRef &key, const StringRef &value); @@ -106,48 +109,55 @@ public: Constant = 0x00000400, Final = 0x00000800 }; - // void setProperty(int index, const StringRef &name, QMetaType::Type type, int notifySignal = -1); - void setProperty(int index, const StringRef &name, const StringRef &type, - QMetaType::Type mtype, PropertyFlag flags, int notifySignal = -1); - void setProperty(int index, const StringRef &name, const StringRef &type, + void setProperty(int index, const StringRef &name, int type, PropertyFlag flags, int notifySignal = -1); - void setMethod(int index, const StringRef &signature, - const StringRef ¶meterNames = StringRef(), - const StringRef &type = StringRef()); - void setSignal(int index, const StringRef &signature, - const StringRef ¶meterNames = StringRef(), - const StringRef &type = StringRef()); + void setMethod(int index, const StringRef &name, int paramIndex, int argc = 0, + const int *types = 0, const StringRef *parameterNames = 0, + QMetaType::Type type = QMetaType::Void); + void setSignal(int index, const StringRef &name, int paramIndex, int argc = 0, + const int *types = 0, const StringRef *parameterNames = 0, + QMetaType::Type type = QMetaType::Void); int metaObjectIndexForSignal(int) const; int metaObjectIndexForMethod(int) const; - QByteArray toData() const { return m_data; } + QByteArray toData() const { + if (m_stringCountLoaded == m_stringCount - 1) { + // zero-string is lazily loaded last + const_cast<StringRef &>(m_zeroString).loadByteArrayData(); + } + Q_ASSERT(m_stringCountLoaded == m_stringCount); + return m_data; + } static void fromData(QMetaObject *, const QMetaObject *parent, const QByteArray &); private: friend struct StringRef; QByteArray m_data; - int m_zeroPtr; + StringRef m_zeroString; void allocateStringData(); - char *m_stringData; + QByteArrayData *m_stringData; + int m_stringCount; int m_stringDataLength; - int m_stringDataAllocated; + int m_stringCountAllocated; + int m_stringCountLoaded; }; QFastMetaBuilder::StringRef::StringRef() -: _b(0), _o(0), _l(0) +: _b(0), _i(0), _o(0), _l(0) { } QFastMetaBuilder::StringRef::StringRef(const StringRef &o) -: _b(o._b), _o(o._o), _l(o._l) +: _b(o._b), _i(o._i), _o(o._o), _l(o._l) { } QFastMetaBuilder::StringRef &QFastMetaBuilder::StringRef::operator=(const StringRef &o) { _b = o._b; + _i = o._i; _o = o._o; _l = o._l; return *this; @@ -163,17 +173,17 @@ QFastMetaBuilder *QFastMetaBuilder::StringRef::builder() const return _b; } -int QFastMetaBuilder::StringRef::offset() const +int QFastMetaBuilder::StringRef::index() const { - return _o; + return _i; } char *QFastMetaBuilder::StringRef::data() { Q_ASSERT(_b); - if (_b->m_stringDataLength != _b->m_stringDataAllocated) - _b->allocateStringData(); - return _b->m_stringData + _o; + if (_b->m_stringCountAllocated < _b->m_stringCount) + _b->allocateStringData(); + return reinterpret_cast<char *>(&_b->m_stringData[_b->m_stringCount]) + _o; } int QFastMetaBuilder::StringRef::length() const @@ -186,18 +196,36 @@ void QFastMetaBuilder::StringRef::load(const QHashedStringRef &str) Q_ASSERT(str.utf8length() == _l); str.writeUtf8(data()); *(data() + _l) = 0; + loadByteArrayData(); } void QFastMetaBuilder::StringRef::load(const QByteArray &str) { Q_ASSERT(str.length() == _l); strcpy(data(), str.constData()); + loadByteArrayData(); } void QFastMetaBuilder::StringRef::load(const char *str) { Q_ASSERT(strlen(str) == (uint)_l); strcpy(data(), str); + loadByteArrayData(); +} + +void QFastMetaBuilder::StringRef::loadByteArrayData() +{ + if (_b->m_stringCountAllocated < _b->m_stringCount) + _b->allocateStringData(); + Q_ASSERT(_b->m_stringCountLoaded < _b->m_stringCount); + + int offsetofCstrings = _b->m_stringCount * sizeof(QByteArrayData); + qptrdiff offset = offsetofCstrings + _o - _i * sizeof(QByteArrayData); + + const QByteArrayData bad = { Q_REFCOUNT_INITIALIZE_STATIC, _l, 0, 0, offset }; + memcpy(&_b->m_stringData[_i], &bad, sizeof(QByteArrayData)); + + ++_b->m_stringCountLoaded; } QT_END_NAMESPACE diff --git a/src/qml/qml/ftw/qqmlpool_p.h b/src/qml/qml/ftw/qqmlpool_p.h index e4fa03ce34..8e8f367890 100644 --- a/src/qml/qml/ftw/qqmlpool_p.h +++ b/src/qml/qml/ftw/qqmlpool_p.h @@ -132,6 +132,7 @@ public: Q_ASSERT(index < m_length); return m_data[index]; }; + const T *data() const { return m_data; } private: friend class QQmlPool; List(T *d, int l) : m_length(l), m_data(d) {} diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index c75e4c9681..fadfc9d833 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -1,5 +1,4 @@ SOURCES += \ - $$PWD/qquickapplication.cpp \ $$PWD/qqmlinstruction.cpp \ $$PWD/qquicklistmodel.cpp \ $$PWD/qquicklistmodelworkeragent.cpp \ @@ -40,7 +39,6 @@ SOURCES += \ $$PWD/qqmltypenamecache.cpp \ $$PWD/qqmlscriptstring.cpp \ $$PWD/qquickworkerscript.cpp \ - $$PWD/qqmlimageprovider.cpp \ $$PWD/qqmlnetworkaccessmanagerfactory.cpp \ $$PWD/qqmldirparser.cpp \ $$PWD/qqmlextensionplugin.cpp \ @@ -52,6 +50,7 @@ SOURCES += \ $$PWD/qqmljavascriptexpression.cpp \ $$PWD/qqmlabstractbinding.cpp \ $$PWD/qqmlvaluetypeproxybinding.cpp \ + $$PWD/qqmlglobal.cpp \ HEADERS += \ $$PWD/qqmlglobal_p.h \ @@ -62,7 +61,6 @@ HEADERS += \ $$PWD/qqmlopenmetaobject_p.h \ $$PWD/qqmlvmemetaobject_p.h \ $$PWD/qqml.h \ - $$PWD/qquickapplication_p.h \ $$PWD/qqmlbinding_p.h \ $$PWD/qqmlproperty.h \ $$PWD/qqmlcomponent.h \ @@ -109,7 +107,6 @@ HEADERS += \ $$PWD/qqmlscriptstring.h \ $$PWD/qquickworkerscript_p.h \ $$PWD/qqmlguard_p.h \ - $$PWD/qqmlimageprovider.h \ $$PWD/qqmlnetworkaccessmanagerfactory.h \ $$PWD/qqmldirparser_p.h \ $$PWD/qqmlextensioninterface.h \ diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index c4f48ef63d..d2a02dc712 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -230,8 +230,6 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) if (needsErrorData) { QUrl url = QUrl(m_url); - if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); - delayedError()->error.setUrl(url); delayedError()->error.setLine(m_lineNumber); delayedError()->error.setColumn(m_columnNumber); diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 3afeb03606..b77484c7e5 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -272,7 +272,7 @@ int QQmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a) return -1; if (QQmlDebugService::isDebuggingEnabled()) - QV8DebugService::instance()->signalEmitted(QString::fromAscii(m_signal.signature())); + QV8DebugService::instance()->signalEmitted(QString::fromAscii(m_signal.methodSignature().constData())); QQmlHandlingSignalProfiler prof(m_signal, m_expression); @@ -320,7 +320,7 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method, continue; } - QVariant::Type t = (QVariant::Type)QMetaType::type(type.constData()); + int t = QMetaType::type(type.constData()); if (QQmlMetaType::isQObject(t)) { types[ii] = QMetaType::QObjectStar; QMetaPropertyBuilder prop = mob.addProperty(name, "QObject*"); @@ -331,8 +331,8 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method, if (flags & QMetaType::IsEnumeration) { t = QVariant::Int; propType = "int"; - } else if (t == QVariant::Invalid || - (t >= QVariant::UserType && !(flags & QMetaType::PointerToQObject) && + } else if (t == QMetaType::UnknownType || + (t >= int(QMetaType::User) && !(flags & QMetaType::PointerToQObject) && t != qMetaTypeId<QJSValue>())) { //the UserType clause is to catch registered QFlags QByteArray scope; diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 2b4ede4271..54577f9b92 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -63,7 +63,6 @@ #include "qqmlbinding_p.h" #include <private/qv4compiler_p.h> -#include <QColor> #include <QDebug> #include <QPointF> #include <QSizeF> @@ -71,6 +70,7 @@ #include <QAtomicInt> #include <QtCore/qdebug.h> #include <QtCore/qdatetime.h> +#include <QtCore/qvarlengtharray.h> Q_DECLARE_METATYPE(QList<int>) Q_DECLARE_METATYPE(QList<qreal>) @@ -349,16 +349,16 @@ bool QQmlCompiler::testLiteralAssignment(QQmlScript::Property *prop, break; case QVariant::Vector3D: { - bool ok; - QQmlStringConverters::vector3DFromString(value.asString(), &ok); - if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 3D vector expected")); + QQmlInstruction::instr_storeVector3D::QVector3D v3; + if (!QQmlStringConverters::createFromString(QMetaType::QVector3D, value.asString(), &v3, sizeof(v3))) + COMPILE_EXCEPTION(v, tr("Invalid property assignment: 3D vector expected")); } break; case QVariant::Vector4D: { - bool ok; - QQmlStringConverters::vector4DFromString(value.asString(), &ok); - if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 4D vector expected")); + QQmlInstruction::instr_storeVector4D::QVector4D v4; + if (!QQmlStringConverters::createFromString(QMetaType::QVector4D, value.asString(), &v4, sizeof(v4))) + COMPILE_EXCEPTION(v, tr("Invalid property assignment: 4D vector expected")); } break; default: @@ -563,9 +563,8 @@ void QQmlCompiler::genLiteralAssignment(QQmlScript::Property *prop, case QVariant::Color: { Instruction::StoreColor instr; - QColor c = QQmlStringConverters::colorFromString(v->value.asString()); instr.propertyIndex = prop->index; - instr.value = c.rgba(); + instr.value = QQmlStringConverters::rgbaFromString(v->value.asString()); output->addInstruction(instr); } break; @@ -684,25 +683,16 @@ void QQmlCompiler::genLiteralAssignment(QQmlScript::Property *prop, case QVariant::Vector3D: { Instruction::StoreVector3D instr; - bool ok; - QVector3D vector = QQmlStringConverters::vector3DFromString(v->value.asString(), &ok); instr.propertyIndex = prop->index; - instr.vector.xp = vector.x(); - instr.vector.yp = vector.y(); - instr.vector.zp = vector.z(); + QQmlStringConverters::createFromString(QMetaType::QVector3D, v->value.asString(), &instr.vector, sizeof(instr.vector)); output->addInstruction(instr); } break; case QVariant::Vector4D: { Instruction::StoreVector4D instr; - bool ok; - QVector4D vector = QQmlStringConverters::vector4DFromString(v->value.asString(), &ok); instr.propertyIndex = prop->index; - instr.vector.xp = vector.x(); - instr.vector.yp = vector.y(); - instr.vector.zp = vector.z(); - instr.vector.wp = vector.w(); + QQmlStringConverters::createFromString(QMetaType::QVector4D, v->value.asString(), &instr.vector, sizeof(instr.vector)); output->addInstruction(instr); } break; @@ -2842,32 +2832,37 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod } } + // Size of the array that describes parameter types & names + int paramDataSize = (obj->aggregateDynamicSignalParameterCount() + obj->aggregateDynamicSlotParameterCount()) * 2 + + obj->dynamicProperties.count() // for Changed() signals return types + // Return "parameters" don't have names + - (obj->dynamicSignals.count() + obj->dynamicSlots.count()); + QFastMetaBuilder builder; + int paramIndex; QFastMetaBuilder::StringRef classNameRef = builder.init(newClassName.length(), obj->dynamicProperties.count() - (resolveAlias?0:aliasCount), obj->dynamicSlots.count(), obj->dynamicSignals.count() + obj->dynamicProperties.count(), - defaultProperty?1:0); + defaultProperty?1:0, paramDataSize, ¶mIndex); struct TypeData { Object::DynamicProperty::Type dtype; int metaType; - const char *cppType; } builtinTypes[] = { - { Object::DynamicProperty::Var, QMetaType::QVariant, "QVariant" }, - { Object::DynamicProperty::Variant, QMetaType::QVariant, "QVariant" }, - { Object::DynamicProperty::Int, QMetaType::Int, "int" }, - { Object::DynamicProperty::Bool, QMetaType::Bool, "bool" }, - { Object::DynamicProperty::Real, QMetaType::Double, "double" }, - { Object::DynamicProperty::String, QMetaType::QString, "QString" }, - { Object::DynamicProperty::Url, QMetaType::QUrl, "QUrl" }, - { Object::DynamicProperty::Color, QMetaType::QColor, "QColor" }, - { Object::DynamicProperty::Time, QMetaType::QTime, "QTime" }, - { Object::DynamicProperty::Date, QMetaType::QDate, "QDate" }, - { Object::DynamicProperty::DateTime, QMetaType::QDateTime, "QDateTime" }, + { Object::DynamicProperty::Var, QMetaType::QVariant }, + { Object::DynamicProperty::Variant, QMetaType::QVariant }, + { Object::DynamicProperty::Int, QMetaType::Int }, + { Object::DynamicProperty::Bool, QMetaType::Bool }, + { Object::DynamicProperty::Real, QMetaType::Double }, + { Object::DynamicProperty::String, QMetaType::QString }, + { Object::DynamicProperty::Url, QMetaType::QUrl }, + { Object::DynamicProperty::Color, QMetaType::QColor }, + { Object::DynamicProperty::Time, QMetaType::QTime }, + { Object::DynamicProperty::Date, QMetaType::QDate }, + { Object::DynamicProperty::DateTime, QMetaType::QDateTime }, }; static const int builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData); - QFastMetaBuilder::StringRef typeRefs[builtinTypeCount]; // Reserve dynamic properties if (obj->dynamicProperties.count()) { @@ -2880,18 +2875,16 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod if (p->type != Object::DynamicProperty::Alias || resolveAlias) p->nameRef = builder.newString(p->name.utf8length()); - int propertyType = 0; + int metaType = 0; + int propertyType = 0; // for VMD bool readonly = false; - QFastMetaBuilder::StringRef typeRef; if (p->type == Object::DynamicProperty::Alias) { continue; } else if (p->type < builtinTypeCount) { Q_ASSERT(builtinTypes[p->type].dtype == p->type); - propertyType = builtinTypes[p->type].metaType; - if (typeRefs[p->type].isEmpty()) - typeRefs[p->type] = builder.newString(strlen(builtinTypes[p->type].cppType)); - typeRef = typeRefs[p->type]; + metaType = builtinTypes[p->type].metaType; + propertyType = metaType; } else { Q_ASSERT(p->type == Object::DynamicProperty::CustomList || @@ -2927,9 +2920,9 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod propertyType = qMetaTypeId<QQmlListProperty<QObject> >(); } - p->resolvedCustomTypeName = pool->NewByteArray(customTypeName); - p->typeRef = builder.newString(customTypeName.length()); - typeRef = p->typeRef; + metaType = QMetaType::type(customTypeName); + Q_ASSERT(metaType != QMetaType::UnknownType); + Q_ASSERT(metaType != QMetaType::Void); } if (p->type == Object::DynamicProperty::Var) @@ -2944,17 +2937,13 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod (vmd->propertyData() + effectivePropertyIndex)->propertyType = propertyType; } - if (p->type < builtinTypeCount) - builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, (QMetaType::Type)propertyType, - readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, - effectivePropertyIndex); - else - builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, - readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, - effectivePropertyIndex); + builder.setProperty(effectivePropertyIndex, p->nameRef, metaType, + readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, + effectivePropertyIndex); - p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()")); - builder.setSignal(effectivePropertyIndex, p->changedSignatureRef); + p->changedNameRef = builder.newString(p->name.utf8length() + strlen("Changed")); + builder.setSignal(effectivePropertyIndex, p->changedNameRef, paramIndex); + paramIndex++; effectivePropertyIndex++; } @@ -2967,19 +2956,19 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod totalPropCount = varPropCount + effectivePropertyIndex; for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) { if (p->type == Object::DynamicProperty::Var) { - QFastMetaBuilder::StringRef typeRef = typeRefs[p->type]; if (buildData) { vmd->propertyCount++; (vmd->propertyData() + effectivePropertyIndex)->propertyType = QMetaType::QVariant; } - builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, + builder.setProperty(effectivePropertyIndex, p->nameRef, QMetaType::QVariant, p->isReadOnly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, effectivePropertyIndex); - p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()")); - builder.setSignal(effectivePropertyIndex, p->changedSignatureRef); + p->changedNameRef = builder.newString(p->name.utf8length() + strlen("Changed")); + builder.setSignal(effectivePropertyIndex, p->changedNameRef, paramIndex); + paramIndex++; effectivePropertyIndex++; } @@ -2998,8 +2987,9 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod } // Even if we aren't resolving the alias, we need a fake signal so that the // metaobject remains consistent across the resolve and non-resolve alias runs - p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()")); - builder.setSignal(effectivePropertyIndex, p->changedSignatureRef); + p->changedNameRef = builder.newString(p->name.utf8length() + strlen("Changed")); + builder.setSignal(effectivePropertyIndex, p->changedNameRef, paramIndex); + paramIndex++; effectivePropertyIndex++; aliasIndex++; } @@ -3018,49 +3008,56 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod int signalIndex = 0; for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) { - int paramCount = s->parameterNames.count(); - - int signatureSize = s->name.utf8length() + 2 /* paren */; - int namesSize = 0; - if (paramCount) signatureSize += s->parameterTypesLength() + (paramCount - 1) /* commas */; - if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1) /* commas */; + s->nameRef = builder.newString(s->name.utf8length()); - s->signatureRef = builder.newString(signatureSize); - if (namesSize) s->parameterNamesRef = builder.newString(namesSize); + int paramCount = s->parameterNames.count(); + QVarLengthArray<int, 10> paramTypes(paramCount); + if (paramCount) { + s->parameterNamesRef = pool->NewRawList<QFastMetaBuilder::StringRef>(paramCount); + for (int i = 0; i < paramCount; ++i) { + s->parameterNamesRef[i] = builder.newString(s->parameterNames.at(i).utf8length()); + Q_ASSERT(s->parameterTypes.at(i) < builtinTypeCount); + paramTypes[i] = builtinTypes[s->parameterTypes.at(i)].metaType; + } + } if (buildData) ((QQmlVMEMetaData *)dynamicData.data())->signalCount++; - builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->signatureRef, s->parameterNamesRef); + builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->nameRef, + paramIndex, paramCount, paramTypes.constData(), s->parameterNamesRef.data()); + paramIndex += paramCount*2 + 1; ++signalIndex; } // Reserve dynamic slots if (obj->dynamicSlots.count()) { - // Allocate QVariant string - if (typeRefs[0].isEmpty()) - typeRefs[0] = builder.newString(strlen(builtinTypes[0].cppType)); - typedef QQmlVMEMetaData VMD; int methodIndex = 0; for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) { + s->nameRef = builder.newString(s->name.utf8length()); int paramCount = s->parameterNames.count(); - int signatureSize = s->name.utf8length() + 2 /* paren */; - int namesSize = 0; - if (paramCount) signatureSize += (paramCount * strlen("QVariant") + (paramCount - 1)); - if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */); - - s->signatureRef = builder.newString(signatureSize); - if (namesSize) s->parameterNamesRef = builder.newString(namesSize); + QVarLengthArray<int, 10> paramTypes(paramCount); + if (paramCount) { + s->parameterNamesRef = pool->NewRawList<QFastMetaBuilder::StringRef>(paramCount); + for (int i = 0; i < paramCount; ++i) { + s->parameterNamesRef[i] = builder.newString(s->parameterNames.at(i).size()); + paramTypes[i] = QMetaType::QVariant; + } + } - builder.setMethod(methodIndex, s->signatureRef, s->parameterNamesRef, typeRefs[0]); + builder.setMethod(methodIndex, s->nameRef, paramIndex, paramCount, + paramTypes.constData(), s->parameterNamesRef.data(), QMetaType::QVariant); + paramIndex += paramCount*2 + 1; if (buildData) { QString funcScript; - funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ + + int namesSize = 0; + if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */); + funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ + namesSize + 1 /* rparen */ + s->body.length() + 1 /* rparen */); funcScript = QLatin1String("(function ") + s->name.toString() + QLatin1Char('('); for (int jj = 0; jj < paramCount; ++jj) { @@ -3089,28 +3086,18 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod } } - // Now allocate used builtin types - for (int ii = 0; ii < builtinTypeCount; ++ii) { - if (!typeRefs[ii].isEmpty()) - typeRefs[ii].load(builtinTypes[ii].cppType); - } - // Now allocate properties for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) { - char *d = p->changedSignatureRef.data(); + char *d = p->changedNameRef.data(); p->name.writeUtf8(d); - strcpy(d + p->name.utf8length(), "Changed()"); + strcpy(d + p->name.utf8length(), "Changed"); + p->changedNameRef.loadByteArrayData(); if (p->type == Object::DynamicProperty::Alias && !resolveAlias) continue; p->nameRef.load(p->name); - - if (p->type >= builtinTypeCount) { - Q_ASSERT(p->resolvedCustomTypeName); - p->typeRef.load(*p->resolvedCustomTypeName); - } } // Allocate default property if necessary @@ -3120,39 +3107,18 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod // Now allocate signals for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) { - char *d = s->signatureRef.data(); - char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data(); - s->name.writeUtf8(d); d += s->name.utf8length(); - *d++ = '('; + s->nameRef.load(s->name); - for (int jj = 0; jj < s->parameterNames.count(); ++jj) { - if (jj != 0) { *d++ = ','; *d2++ = ','; } - strcpy(d, s->parameterTypes.at(jj).constData()); - d += s->parameterTypes.at(jj).length(); - s->parameterNames.at(jj).writeUtf8(d2); - d2 += s->parameterNames.at(jj).utf8length(); - } - *d++ = ')'; - *d = 0; - if (d2) *d2 = 0; + for (int jj = 0; jj < s->parameterNames.count(); ++jj) + s->parameterNamesRef[jj].load(s->parameterNames.at(jj)); } // Now allocate methods for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) { - char *d = s->signatureRef.data(); - char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data(); - s->name.writeUtf8(d); d += s->name.utf8length(); - *d++ = '('; - for (int jj = 0; jj < s->parameterNames.count(); ++jj) { - if (jj != 0) { *d++ = ','; *d2++ = ','; } - strcpy(d, "QVariant"); - d += strlen("QVariant"); - strcpy(d2, s->parameterNames.at(jj).constData()); - d2 += s->parameterNames.at(jj).length(); - } - *d++ = ')'; - *d = 0; - if (d2) *d2 = 0; + s->nameRef.load(s->name); + + for (int jj = 0; jj < s->parameterNames.count(); ++jj) + s->parameterNamesRef[jj].load(s->parameterNames.at(jj).constData()); } // Now allocate class name @@ -3245,7 +3211,6 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, Object::DynamicProperty &prop) { Q_ASSERT(!prop.nameRef.isEmpty()); - Q_ASSERT(prop.typeRef.isEmpty()); if (!prop.defaultValue) COMPILE_EXCEPTION(obj, tr("No property alias location")); @@ -3290,9 +3255,7 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, writable = aliasProperty.isWritable() && !prop.isReadOnly; resettable = aliasProperty.isResettable() && !prop.isReadOnly; - if (aliasProperty.type() < QVariant::UserType - || uint(aliasProperty.type()) == QMetaType::QVariant) - type = aliasProperty.type(); + type = aliasProperty.userType(); if (alias.count() == 3) { QQmlValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()]; @@ -3310,9 +3273,7 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, propIdx |= (valueTypeIndex << 16); // update the property type - type = aliasProperty.type(); - if (type >= (int)QVariant::UserType) - type = 0; + type = aliasProperty.userType(); } if (aliasProperty.isEnumType()) @@ -3334,22 +3295,26 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, if (typeName.endsWith('*')) flags |= QML_ALIAS_FLAG_PTR; + if (type == QMetaType::UnknownType) { + Q_ASSERT(!typeName.isEmpty()); + type = QMetaType::type(typeName); + Q_ASSERT(type != QMetaType::UnknownType); + Q_ASSERT(type != QMetaType::Void); + } + QQmlVMEMetaData::AliasData aliasData = { idObject->idIndex, propIdx, flags }; typedef QQmlVMEMetaData VMD; VMD *vmd = (QQmlVMEMetaData *)data.data(); *(vmd->aliasData() + aliasIndex) = aliasData; - prop.resolvedCustomTypeName = pool->NewByteArray(typeName); - prop.typeRef = builder.newString(typeName.length()); - int propertyFlags = 0; if (writable) propertyFlags |= QFastMetaBuilder::Writable; if (resettable) propertyFlags |= QFastMetaBuilder::Resettable; - builder.setProperty(propIndex, prop.nameRef, prop.typeRef, (QMetaType::Type)type, + builder.setProperty(propIndex, prop.nameRef, type, (QFastMetaBuilder::PropertyFlag)propertyFlags, propIndex); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 19d1750e39..153d6b325a 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -59,14 +59,12 @@ #include "qquickworkerscript_p.h" #include "qqmlcomponent_p.h" #include "qqmlnetworkaccessmanagerfactory.h" -#include "qqmlimageprovider.h" #include "qqmldirparser_p.h" #include "qqmlextensioninterface.h" #include "qqmllist_p.h" #include "qqmltypenamecache_p.h" #include "qqmlnotifier_p.h" #include <private/qqmlprofilerservice_p.h> -#include <private/qquickapplication_p.h> #include <private/qv8debugservice_p.h> #include <private/qdebugmessageservice_p.h> #include "qqmlincubator.h" @@ -176,10 +174,47 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int void QQmlEnginePrivate::defineModule() { registerBaseTypes("QtQuick", 2, 0); - qmlRegisterUncreatableType<QQuickApplication>("QtQuick",2,0,"Application", QQuickApplication::tr("Application is an abstract class")); qmlRegisterUncreatableType<QQmlLocale>("QtQuick",2,0,"Locale",QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()")); } + +/*! + \class QQmlImageProviderBase + \brief The QQmlImageProviderBase class is used to register image providers in the QML engine. + \mainclass + + Image providers must be registered with the QML engine. The only information the QML + engine knows about image providers is the type of image data they provide. To use an + image provider to acquire image data, you must cast the QQmlImageProviderBase pointer + to a QQuickImageProvider pointer. + + \sa QQuickImageProvider, QQuickTextureFactory +*/ + +/*! + \enum QQmlImageProviderBase::ImageType + + Defines the type of image supported by this image provider. + + \value Image The Image Provider provides QImage images. + The QQuickImageProvider::requestImage() method will be called for all image requests. + \value Pixmap The Image Provider provides QPixmap images. + The QQuickImageProvider::requestPixmap() method will be called for all image requests. + \value Texture The Image Provider provides QSGTextureProvider based images. + The QQuickImageProvider::requestTexture() method will be called for all image requests. \omitvalue +*/ + +/*! \internal */ +QQmlImageProviderBase::QQmlImageProviderBase() +{ +} + +/*! \internal */ +QQmlImageProviderBase::~QQmlImageProviderBase() +{ +} + + /*! \qmlclass Qt QQmlEnginePrivate \ingroup qml-utility-elements @@ -682,27 +717,29 @@ QNetworkAccessManager *QQmlEngine::networkAccessManager() const takes ownership of \a provider. Image providers enable support for pixmap and threaded image - requests. See the QQmlImageProvider documentation for details on + requests. See the QQuickImageProvider documentation for details on implementing and using image providers. All required image providers should be added to the engine before any QML sources files are loaded. - \sa removeImageProvider() + \sa removeImageProvider(), QQuickImageProvider, QQmlImageProviderBase */ -void QQmlEngine::addImageProvider(const QString &providerId, QQmlImageProvider *provider) +void QQmlEngine::addImageProvider(const QString &providerId, QQmlImageProviderBase *provider) { Q_D(QQmlEngine); QMutexLocker locker(&d->mutex); - d->imageProviders.insert(providerId.toLower(), QSharedPointer<QQmlImageProvider>(provider)); + d->imageProviders.insert(providerId.toLower(), QSharedPointer<QQmlImageProviderBase>(provider)); } /*! - Returns the QQmlImageProvider set for \a providerId. + Returns the image provider set for \a providerId. Returns the provider if it was found; otherwise returns 0. + + \sa QQuickImageProvider */ -QQmlImageProvider *QQmlEngine::imageProvider(const QString &providerId) const +QQmlImageProviderBase *QQmlEngine::imageProvider(const QString &providerId) const { Q_D(const QQmlEngine); QMutexLocker locker(&d->mutex); @@ -710,9 +747,9 @@ QQmlImageProvider *QQmlEngine::imageProvider(const QString &providerId) const } /*! - Removes the QQmlImageProvider for \a providerId. + Removes the image provider for \a providerId. - \sa addImageProvider() + \sa addImageProvider(), QQuickImageProvider */ void QQmlEngine::removeImageProvider(const QString &providerId) { @@ -721,54 +758,6 @@ void QQmlEngine::removeImageProvider(const QString &providerId) d->imageProviders.take(providerId); } -QQmlImageProvider::ImageType QQmlEnginePrivate::getImageProviderType(const QUrl &url) -{ - QMutexLocker locker(&mutex); - QSharedPointer<QQmlImageProvider> provider = imageProviders.value(url.host()); - locker.unlock(); - if (provider) - return provider->imageType(); - return QQmlImageProvider::Invalid; -} - -QQuickTextureFactory *QQmlEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size) -{ - QMutexLocker locker(&mutex); - QSharedPointer<QQmlImageProvider> provider = imageProviders.value(url.host()); - locker.unlock(); - if (provider) { - QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1); - return provider->requestTexture(imageId, size, req_size); - } - return 0; -} - -QImage QQmlEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size) -{ - QMutexLocker locker(&mutex); - QImage image; - QSharedPointer<QQmlImageProvider> provider = imageProviders.value(url.host()); - locker.unlock(); - if (provider) { - QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1); - image = provider->requestImage(imageId, size, req_size); - } - return image; -} - -QPixmap QQmlEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size) -{ - QMutexLocker locker(&mutex); - QPixmap pixmap; - QSharedPointer<QQmlImageProvider> provider = imageProviders.value(url.host()); - locker.unlock(); - if (provider) { - QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1); - pixmap = provider->requestPixmap(imageId, size, req_size); - } - return pixmap; -} - /*! Return the base URL for this engine. The base URL is only used to resolve components when a relative URL is passed to the diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 04ac61c05b..21a03d63ce 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -54,6 +54,25 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +class Q_QML_EXPORT QQmlImageProviderBase +{ +public: + enum ImageType { + Image, + Pixmap, + Texture, + Invalid + }; + + virtual ~QQmlImageProviderBase(); + + virtual ImageType imageType() const = 0; + +private: + friend class QQuickImageProvider; + QQmlImageProviderBase(); +}; + class QQmlComponent; class QQmlEnginePrivate; class QQmlImportsPrivate; @@ -62,7 +81,6 @@ class QQmlContext; class QQmlType; class QUrl; class QScriptContext; -class QQmlImageProvider; class QNetworkAccessManager; class QQmlNetworkAccessManagerFactory; class QQmlIncubationController; @@ -94,8 +112,8 @@ public: QNetworkAccessManager *networkAccessManager() const; - void addImageProvider(const QString &id, QQmlImageProvider *); - QQmlImageProvider *imageProvider(const QString &id) const; + void addImageProvider(const QString &id, QQmlImageProviderBase *); + QQmlImageProviderBase *imageProvider(const QString &id) const; void removeImageProvider(const QString &id); void setIncubationController(QQmlIncubationController *); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index db834489ba..73a0b5a217 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -63,7 +63,6 @@ #include "qqmlcontext.h" #include "qqmlcontext_p.h" #include "qqmlexpression.h" -#include "qqmlimageprovider.h" #include "qqmlproperty_p.h" #include "qqmlpropertycache_p.h" #include "qqmlmetatype_p.h" @@ -173,11 +172,7 @@ public: mutable QNetworkAccessManager *networkAccessManager; mutable QQmlNetworkAccessManagerFactory *networkAccessManagerFactory; - QHash<QString,QSharedPointer<QQmlImageProvider> > imageProviders; - QQmlImageProvider::ImageType getImageProviderType(const QUrl &url); - QQuickTextureFactory *getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size); - QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size); - QPixmap getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size); + QHash<QString,QSharedPointer<QQmlImageProviderBase> > imageProviders; // Scarce resources are "exceptionally high cost" QVariant types where allowing the // normal JavaScript GC to clean them up is likely to lead to out-of-memory or other diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h index 3c148549d0..73581e29aa 100644 --- a/src/qml/qml/qqmlerror.h +++ b/src/qml/qml/qqmlerror.h @@ -80,6 +80,8 @@ private: QDebug Q_QML_EXPORT operator<<(QDebug debug, const QQmlError &error); +Q_DECLARE_TYPEINFO(QQmlError, Q_MOVABLE_TYPE); + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp new file mode 100644 index 0000000000..1f8de4fae8 --- /dev/null +++ b/src/qml/qml/qqmlglobal.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qqmlglobal_p.h> + +#include <QtCore/qvariant.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +QQmlValueTypeProvider::QQmlValueTypeProvider() + : next(0) +{ +} + +QQmlValueType *QQmlValueTypeProvider::createValueType(int type) +{ + QQmlValueType *value = 0; + + QQmlValueTypeProvider *p = this; + do { + if (p->create(type, value)) + return value; + } while ((p = p->next)); + + return 0; +} + +bool QQmlValueTypeProvider::initValueType(int type, void *data, size_t n) +{ + Q_ASSERT(data); + + QQmlValueTypeProvider *p = this; + do { + if (p->init(type, data, n)) + return true; + } while ((p = p->next)); + + return false; +} + +bool QQmlValueTypeProvider::destroyValueType(int type, void *data, size_t n) +{ + Q_ASSERT(data); + + QQmlValueTypeProvider *p = this; + do { + if (p->destroy(type, data, n)) + return true; + } while ((p = p->next)); + + return false; +} + +bool QQmlValueTypeProvider::copyValueType(int type, const void *src, void *dst, size_t n) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + QQmlValueTypeProvider *p = this; + do { + if (p->copy(type, src, dst, n)) + return true; + } while ((p = p->next)); + + return false; +} + +QVariant QQmlValueTypeProvider::createValueType(int type, int argc, const void *argv[]) +{ + QVariant v; + + QQmlValueTypeProvider *p = this; + do { + if (p->create(type, argc, argv, &v)) + return v; + } while ((p = p->next)); + + return QVariant(); +} + +bool QQmlValueTypeProvider::createValueFromString(int type, const QString &s, void *data, size_t n) +{ + Q_ASSERT(data); + + QQmlValueTypeProvider *p = this; + do { + if (p->createFromString(type, s, data, n)) + return true; + } while ((p = p->next)); + + return false; +} + +bool QQmlValueTypeProvider::createStringFromValue(int type, const void *data, QString *s) +{ + Q_ASSERT(data); + Q_ASSERT(s); + + QQmlValueTypeProvider *p = this; + do { + if (p->createStringFrom(type, data, s)) + return true; + } while ((p = p->next)); + + return false; +} + +QVariant QQmlValueTypeProvider::createVariantFromString(const QString &s) +{ + QVariant v; + + QQmlValueTypeProvider *p = this; + do { + if (p->variantFromString(s, &v)) + return v; + } while ((p = p->next)); + + // Return a variant containing the string itself + return QVariant(s); +} + +QVariant QQmlValueTypeProvider::createVariantFromString(int type, const QString &s, bool *ok) +{ + QVariant v; + + QQmlValueTypeProvider *p = this; + do { + if (p->variantFromString(type, s, &v)) { + if (ok) *ok = true; + return v; + } + } while ((p = p->next)); + + if (ok) *ok = false; + return QVariant(); +} + +bool QQmlValueTypeProvider::storeValueType(int type, const void *src, void *dst, size_t n) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + QQmlValueTypeProvider *p = this; + do { + if (p->store(type, src, dst, n)) + return true; + } while ((p = p->next)); + + return false; +} + +bool QQmlValueTypeProvider::readValueType(int srcType, const void *src, int dstType, void *dst) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + QQmlValueTypeProvider *p = this; + do { + if (p->read(srcType, src, dstType, dst)) + return true; + } while ((p = p->next)); + + return false; +} + +bool QQmlValueTypeProvider::writeValueType(int type, const void *src, void *dst, size_t n) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + QQmlValueTypeProvider *p = this; + do { + if (p->write(type, src, dst, n)) + return true; + } while ((p = p->next)); + + return false; +} + +bool QQmlValueTypeProvider::create(int, QQmlValueType *&) { return false; } +bool QQmlValueTypeProvider::init(int, void *, size_t) { return false; } +bool QQmlValueTypeProvider::destroy(int, void *, size_t) { return false; } +bool QQmlValueTypeProvider::copy(int, const void *, void *, size_t) { return false; } +bool QQmlValueTypeProvider::create(int, int, const void *[], QVariant *) { return false; } +bool QQmlValueTypeProvider::createFromString(int, const QString &, void *, size_t) { return false; } +bool QQmlValueTypeProvider::createStringFrom(int, const void *, QString *) { return false; } +bool QQmlValueTypeProvider::variantFromString(const QString &, QVariant *) { return false; } +bool QQmlValueTypeProvider::variantFromString(int, const QString &, QVariant *) { return false; } +bool QQmlValueTypeProvider::store(int, const void *, void *, size_t) { return false; } +bool QQmlValueTypeProvider::read(int, const void *, int, void *) { return false; } +bool QQmlValueTypeProvider::write(int, const void *, void *, size_t) { return false; } + +static QQmlValueTypeProvider *valueTypeProvider = 0; + +static QQmlValueTypeProvider **getValueTypeProvider(void) +{ + if (valueTypeProvider == 0) { + static QQmlValueTypeProvider nullValueTypeProvider; + valueTypeProvider = &nullValueTypeProvider; + } + + return &valueTypeProvider; +} + +Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *newProvider) +{ + static QQmlValueTypeProvider **providerPtr = getValueTypeProvider(); + newProvider->next = *providerPtr; + *providerPtr = newProvider; +} + +Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider(void) +{ + if (valueTypeProvider == 0) { + qWarning() << "Warning: QQml_valueTypeProvider: no value type provider has been set!"; + } + + static QQmlValueTypeProvider **providerPtr = getValueTypeProvider(); + return *providerPtr; +} + + +QVariant QQmlColorProvider::colorFromString(const QString &, bool *ok) { if (ok) *ok = false; return QVariant(); } +unsigned QQmlColorProvider::rgbaFromString(const QString &, bool *ok) { if (ok) *ok = false; return 0; } +QVariant QQmlColorProvider::fromRgbF(double, double, double, double) { return QVariant(); } +QVariant QQmlColorProvider::fromHslF(double, double, double, double) { return QVariant(); } +QVariant QQmlColorProvider::lighter(const QVariant &, qreal) { return QVariant(); } +QVariant QQmlColorProvider::darker(const QVariant &, qreal) { return QVariant(); } +QVariant QQmlColorProvider::tint(const QVariant &, const QVariant &) { return QVariant(); } + +static QQmlColorProvider *colorProvider = 0; + +Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_setColorProvider(QQmlColorProvider *newProvider) +{ + QQmlColorProvider *old = colorProvider; + colorProvider = newProvider; + return old; +} + +static QQmlColorProvider **getColorProvider(void) +{ + if (colorProvider == 0) { + qWarning() << "Warning: QQml_colorProvider: no color provider has been set!"; + static QQmlColorProvider nullColorProvider; + colorProvider = &nullColorProvider; + } + + return &colorProvider; +} + +Q_AUTOTEST_EXPORT QQmlColorProvider *QQml_colorProvider(void) +{ + static QQmlColorProvider **providerPtr = getColorProvider(); + return *providerPtr; +} + + +QObject *QQmlGuiProvider::application(QObject *) { return 0; } +QStringList QQmlGuiProvider::fontFamilies() { return QStringList(); } +bool QQmlGuiProvider::openUrlExternally(QUrl &) { return false; } + +QObject *QQmlGuiProvider::inputMethod() +{ + // We don't have any input method code by default + QObject *o = new QObject(); + o->setObjectName(QString::fromAscii("No inputMethod available")); + return o; +} + +static QQmlGuiProvider *guiProvider = 0; + +Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newProvider) +{ + QQmlGuiProvider *old = guiProvider; + guiProvider = newProvider; + return old; +} + +static QQmlGuiProvider **getGuiProvider(void) +{ + if (guiProvider == 0) { + qWarning() << "Warning: QQml_guiProvider: no GUI provider has been set!"; + static QQmlGuiProvider nullGuiProvider; + guiProvider = &nullGuiProvider; + } + + return &guiProvider; +} + +Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(void) +{ + static QQmlGuiProvider **providerPtr = getGuiProvider(); + return *providerPtr; +} + +QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index c41b823e60..2356b2d122 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -42,7 +42,7 @@ #ifndef QQMLGLOBAL_H #define QQMLGLOBAL_H -#include <QtCore/qglobal.h> +#include <private/qtqmlglobal_p.h> #include <QtCore/QObject> QT_BEGIN_HEADER @@ -122,6 +122,87 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent) static_cast<QQmlGraphics_DerivedObject *>(object)->setParent_noEvent(parent); } + +class QQmlValueType; + +class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider +{ +public: + QQmlValueTypeProvider(); + + QQmlValueType *createValueType(int); + + bool initValueType(int, void *, size_t); + bool destroyValueType(int, void *, size_t); + bool copyValueType(int, const void *, void *, size_t); + + QVariant createValueType(int, int, const void *[]); + bool createValueFromString(int, const QString &, void *, size_t); + bool createStringFromValue(int, const void *, QString *); + + QVariant createVariantFromString(const QString &); + QVariant createVariantFromString(int, const QString &, bool *); + + bool storeValueType(int, const void *, void *, size_t); + bool readValueType(int, const void *, int, void *); + bool writeValueType(int, const void *, void *, size_t); + +private: + virtual bool create(int, QQmlValueType *&); + + virtual bool init(int, void *, size_t); + virtual bool destroy(int, void *, size_t); + virtual bool copy(int, const void *, void *, size_t); + + virtual bool create(int, int, const void *[], QVariant *); + virtual bool createFromString(int, const QString &, void *, size_t); + virtual bool createStringFrom(int, const void *, QString *); + + virtual bool variantFromString(const QString &, QVariant *); + virtual bool variantFromString(int, const QString &, QVariant *); + + virtual bool store(int, const void *, void *, size_t); + virtual bool read(int, const void *, int, void *); + virtual bool write(int, const void *, void *, size_t); + + friend Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *); + + QQmlValueTypeProvider *next; +}; + +Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *); +Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider(); + + +class Q_QML_PRIVATE_EXPORT QQmlColorProvider +{ +public: + virtual QVariant colorFromString(const QString &, bool *); + virtual unsigned rgbaFromString(const QString &, bool *); + + virtual QVariant fromRgbF(double, double, double, double); + virtual QVariant fromHslF(double, double, double, double); + virtual QVariant lighter(const QVariant &, qreal); + virtual QVariant darker(const QVariant &, qreal); + virtual QVariant tint(const QVariant &, const QVariant &); +}; + +Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_setColorProvider(QQmlColorProvider *); +Q_AUTOTEST_EXPORT QQmlColorProvider *QQml_colorProvider(); + + +class Q_QML_PRIVATE_EXPORT QQmlGuiProvider +{ +public: + virtual QObject *application(QObject *parent); + virtual QObject *inputMethod(); + virtual QStringList fontFamilies(); + virtual bool openUrlExternally(QUrl &); +}; + +Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *); +Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(); + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index aad6a04714..569a292a8b 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -263,7 +263,7 @@ void QQmlJavaScriptExpression::exceptionToError(v8::Handle<v8::Message> message, v8::Local<v8::String> file = name->IsString()?name->ToString():v8::Local<v8::String>(); if (file.IsEmpty() || file->Length() == 0) - error.setUrl(QUrl(QLatin1String("<Unknown File>"))); + error.setUrl(QUrl()); else error.setUrl(QUrl(QV8Engine::toStringStatic(file))); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index d4c19f8325..856f75fc16 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -340,9 +340,7 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, QMetaMethod method = mo->method(ii); // More complex - need to search name - QByteArray name = method.signature(); - int parenIdx = name.indexOf('('); - if (parenIdx != -1) name = name.left(parenIdx); + QByteArray name = method.name(); bool found = false; @@ -352,11 +350,8 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, ++ii) { QMetaMethod other = ignoreEnd->method(ii); - QByteArray othername = other.signature(); - int parenIdx = othername.indexOf('('); - if (parenIdx != -1) othername = othername.left(parenIdx); - found = name == othername; + found = name == other.name(); } QMetaMethodBuilder m = builder.addMethod(method); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index e010fd510c..075c1f6c4f 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -337,7 +337,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) signalName[0] = signalName.at(0).toLower(); QMetaMethod method = findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData()); - if (method.signature()) { + if (method.isValid()) { object = currentObject; core.load(method); return; @@ -1156,7 +1156,7 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, return false; } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) { int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope() + QByteArray("::") + menum.name())); - if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData()) + if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData()) return false; v = QVariant(*reinterpret_cast<const int *>(v.constData())); } @@ -1495,6 +1495,17 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, if (expression->hasError()) { return false; + } else if (isVmeProperty) { + typedef QQmlVMEMetaObject VMEMO; + if (!result.IsEmpty() && result->IsFunction() + && !result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) { + // we explicitly disallow this case to avoid confusion. Users can still store one + // in an array in a var property if they need to, but the common case is user error. + expression->delayedError()->error.setDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration.")); + return false; + } + VMEMO *vmemo = static_cast<VMEMO *>(const_cast<QMetaObject *>(object->metaObject())); + vmemo->setVMEProperty(core.coreIndex, result); } else if (isUndefined && core.isResettable()) { void *args[] = { 0 }; QMetaObject::metacall(object, QMetaObject::ResetProperty, core.coreIndex, args); @@ -1504,12 +1515,11 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, expression->delayedError()->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(type))); return false; } else if (result->IsFunction()) { - expression->delayedError()->error.setDescription(QLatin1String("Unable to assign a function to a property.")); + if (!result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) + expression->delayedError()->error.setDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration.")); + else + expression->delayedError()->error.setDescription(QLatin1String("Unable to assign a function to a property of any type other than var.")); return false; - } else if (isVmeProperty) { - typedef QQmlVMEMetaObject VMEMO; - VMEMO *vmemo = static_cast<VMEMO *>(const_cast<QMetaObject *>(object->metaObject())); - vmemo->setVMEProperty(core.coreIndex, result); } else if (!writeValueProperty(object, engine, core, value, context, flags)) { if (watcher.wasDeleted()) @@ -1704,7 +1714,7 @@ bool QQmlProperty::connectNotifySignal(QObject *dest, const char *slot) const QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex); if (prop.hasNotifySignal()) { - QByteArray signal(QByteArray("2") + prop.notifySignal().signature()); + QByteArray signal(QByteArray("2") + prop.notifySignal().methodSignature()); return QObject::connect(d->object, signal.constData(), dest, slot); } else { return false; @@ -1810,11 +1820,8 @@ QMetaMethod QQmlPropertyPrivate::findSignalByName(const QMetaObject *mo, const Q int methods = mo->methodCount(); for (int ii = methods - 1; ii >= 2; --ii) { // >= 2 to block the destroyed signal QMetaMethod method = mo->method(ii); - QByteArray methodName = method.signature(); - int idx = methodName.indexOf('('); - methodName = methodName.left(idx); - if (methodName == name) + if (method.name() == name) return method; } diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h index 2c4b2544c1..bd2b1d35ba 100644 --- a/src/qml/qml/qqmlproperty.h +++ b/src/qml/qml/qqmlproperty.h @@ -136,6 +136,8 @@ inline uint qHash (const QQmlProperty &key) return qHash(key.object()) + qHash(key.name()); } +Q_DECLARE_TYPEINFO(QQmlProperty, Q_MOVABLE_TYPE); + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 50fd409a00..1e8cfb6c20 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -176,19 +176,11 @@ void QQmlPropertyData::load(const QMetaMethod &m) flags |= IsFunction; if (m.methodType() == QMetaMethod::Signal) flags |= IsSignal; - propType = QVariant::Invalid; + propType = m.returnType(); - const char *returnType = m.typeName(); - if (returnType) - propType = QMetaType::type(returnType); - - const char *signature = m.signature(); - while (*signature != '(') { Q_ASSERT(*signature != 0); ++signature; } - - ++signature; - if (*signature != ')') { + if (m.parameterCount()) { flags |= HasArguments; - if (0 == ::strcmp(signature, "QQmlV8Function*)")) { + if ((m.parameterCount() == 1) && (m.parameterTypes().first() == "QQmlV8Function*")) { flags |= IsV8Function; } } @@ -204,21 +196,18 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m) flags |= IsFunction; if (m.methodType() == QMetaMethod::Signal) flags |= IsSignal; - propType = QVariant::Invalid; + propType = QMetaType::Void; const char *returnType = m.typeName(); - if (returnType && *returnType) { + Q_ASSERT(returnType != 0); + if ((*returnType != 'v') || (qstrcmp(returnType+1, "oid") != 0)) { propTypeName = returnType; flags |= NotFullyResolved; } - const char *signature = m.signature(); - while (*signature != '(') { Q_ASSERT(*signature != 0); ++signature; } - - ++signature; - if (*signature != ')') { + if (m.parameterCount()) { flags |= HasArguments; - if (0 == ::strcmp(signature, "QQmlV8Function*)")) { + if ((m.parameterCount() == 1) && (m.parameterTypes().first() == "QQmlV8Function*")) { flags |= IsV8Function; } } @@ -414,10 +403,17 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject continue; // Extract method name - const char *signature = m.signature(); + const char *signature; + if (QMetaObjectPrivate::get(metaObject)->revision >= 7) { + // Safe to use the raw name pointer + signature = m.name().constData(); + } else { + // Safe to use the raw signature pointer + signature = m.methodSignature().constData(); + } const char *cptr = signature; char utf8 = 0; - while (*cptr != '(') { + while (*cptr && *cptr != '(') { Q_ASSERT(*cptr != 0); utf8 |= *cptr & 0x80; ++cptr; @@ -663,11 +659,7 @@ QString QQmlPropertyData::name(const QMetaObject *metaObject) if (flags & IsFunction) { QMetaMethod m = metaObject->method(coreIndex); - QString name = QString::fromUtf8(m.signature()); - int parenIdx = name.indexOf(QLatin1Char('(')); - if (parenIdx != -1) - name = name.left(parenIdx); - return name; + return QString::fromUtf8(m.name().constData()); } else { QMetaProperty p = metaObject->property(coreIndex); return QString::fromUtf8(p.name()); @@ -738,22 +730,26 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, const QMetaObject *metaObject = object->metaObject(); QMetaMethod m = metaObject->method(index); - QList<QByteArray> argTypeNames = m.parameterTypes(); - A *args = static_cast<A *>(malloc(sizeof(A) + (argTypeNames.count() + 1) * sizeof(int))); - args->arguments[0] = argTypeNames.count(); + int argc = m.parameterCount(); + A *args = static_cast<A *>(malloc(sizeof(A) + (argc + 1) * sizeof(int))); + args->arguments[0] = argc; + QList<QByteArray> argTypeNames; // Only loaded if needed - for (int ii = 0; ii < argTypeNames.count(); ++ii) { - int type = QMetaType::type(argTypeNames.at(ii)); + for (int ii = 0; ii < argc; ++ii) { + int type = m.parameterType(ii); QMetaType::TypeFlags flags = QMetaType::typeFlags(type); if (flags & QMetaType::IsEnumeration) type = QVariant::Int; - else if (type == QVariant::Invalid || + else if (type == QMetaType::UnknownType || (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) && - type != qMetaTypeId<QJSValue>())) + type != qMetaTypeId<QJSValue>())) { //the UserType clause is to catch registered QFlags + if (argTypeNames.isEmpty()) + argTypeNames = m.parameterTypes(); type = EnumType(object->metaObject(), argTypeNames.at(ii), type); - if (type == QVariant::Invalid) { + } + if (type == QMetaType::UnknownType) { if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii); free(args); return 0; @@ -768,21 +764,25 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, } else { QMetaMethod m = object->metaObject()->method(index); - QList<QByteArray> argTypeNames = m.parameterTypes(); - dummy.resize(argTypeNames.count() + 1); - dummy[0] = argTypeNames.count(); + int argc = m.parameterCount(); + dummy.resize(argc + 1); + dummy[0] = argc; + QList<QByteArray> argTypeNames; // Only loaded if needed - for (int ii = 0; ii < argTypeNames.count(); ++ii) { - int type = QMetaType::type(argTypeNames.at(ii)); + for (int ii = 0; ii < argc; ++ii) { + int type = m.parameterType(ii); QMetaType::TypeFlags flags = QMetaType::typeFlags(type); if (flags & QMetaType::IsEnumeration) type = QVariant::Int; - else if (type == QVariant::Invalid || + else if (type == QMetaType::UnknownType || (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) && - type != qMetaTypeId<QJSValue>())) + type != qMetaTypeId<QJSValue>())) { //the UserType clause is to catch registered QFlags) + if (argTypeNames.isEmpty()) + argTypeNames = m.parameterTypes(); type = EnumType(object->metaObject(), argTypeNames.at(ii), type); - if (type == QVariant::Invalid) { + } + if (type == QMetaType::UnknownType) { if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii); return 0; } @@ -827,13 +827,9 @@ QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, QMetaMethod m = metaObject->method(ii); if (m.access() == QMetaMethod::Private) continue; - QString methodName = QString::fromUtf8(m.signature()); - - int parenIdx = methodName.indexOf(QLatin1Char('(')); - Q_ASSERT(parenIdx != -1); - QStringRef methodNameRef = methodName.leftRef(parenIdx); + QString methodName = QString::fromUtf8(m.name().constData()); - if (methodNameRef == property) { + if (methodName == property) { rv.load(m); return rv; } diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp index 900dd04863..37c0fb44a4 100644 --- a/src/qml/qml/qqmlscript.cpp +++ b/src/qml/qml/qqmlscript.cpp @@ -187,33 +187,30 @@ Property *QQmlScript::Object::getProperty(const QString &name, bool create) } } -QQmlScript::Object::DynamicProperty::DynamicProperty() -: isDefaultProperty(false), isReadOnly(false), type(Variant), defaultValue(0), nextProperty(0), - resolvedCustomTypeName(0) +int QQmlScript::Object::aggregateDynamicSignalParameterCount() const { + int sum = 0; + for (DynamicSignal *s = dynamicSignals.first(); s; s = dynamicSignals.next(s)) + sum += s->parameterTypes.count() + 1; // +1 for return type + return sum; } -QQmlScript::Object::DynamicSignal::DynamicSignal() -: nextSignal(0) +int QQmlScript::Object::aggregateDynamicSlotParameterCount() const { + int sum = 0; + for (DynamicSlot *s = dynamicSlots.first(); s; s = dynamicSlots.next(s)) + sum += s->parameterNames.count() + 1; // +1 for return type + return sum; } -// Returns length in utf8 bytes -int QQmlScript::Object::DynamicSignal::parameterTypesLength() const +QQmlScript::Object::DynamicProperty::DynamicProperty() +: isDefaultProperty(false), isReadOnly(false), type(Variant), defaultValue(0), nextProperty(0) { - int rv = 0; - for (int ii = 0; ii < parameterTypes.count(); ++ii) - rv += parameterTypes.at(ii).length(); - return rv; } -// Returns length in utf8 bytes -int QQmlScript::Object::DynamicSignal::parameterNamesLength() const +QQmlScript::Object::DynamicSignal::DynamicSignal() +: nextSignal(0) { - int rv = 0; - for (int ii = 0; ii < parameterNames.count(); ++ii) - rv += parameterNames.at(ii).utf8length(); - return rv; } QQmlScript::Object::DynamicSlot::DynamicSlot() @@ -924,25 +921,23 @@ bool ProcessAST::visit(AST::UiPublicMember *node) const char *name; int nameLength; Object::DynamicProperty::Type type; - const char *qtName; - int qtNameLength; } propTypeNameToTypes[] = { - { "int", strlen("int"), Object::DynamicProperty::Int, "int", strlen("int") }, - { "bool", strlen("bool"), Object::DynamicProperty::Bool, "bool", strlen("bool") }, - { "double", strlen("double"), Object::DynamicProperty::Real, "double", strlen("double") }, - { "real", strlen("real"), Object::DynamicProperty::Real, "double", strlen("double") }, - { "string", strlen("string"), Object::DynamicProperty::String, "QString", strlen("QString") }, - { "url", strlen("url"), Object::DynamicProperty::Url, "QUrl", strlen("QUrl") }, - { "color", strlen("color"), Object::DynamicProperty::Color, "QColor", strlen("QColor") }, + { "int", strlen("int"), Object::DynamicProperty::Int }, + { "bool", strlen("bool"), Object::DynamicProperty::Bool }, + { "double", strlen("double"), Object::DynamicProperty::Real }, + { "real", strlen("real"), Object::DynamicProperty::Real }, + { "string", strlen("string"), Object::DynamicProperty::String }, + { "url", strlen("url"), Object::DynamicProperty::Url }, + { "color", strlen("color"), Object::DynamicProperty::Color }, // Internally QTime, QDate and QDateTime are all supported. // To be more consistent with JavaScript we expose only // QDateTime as it matches closely with the Date JS type. // We also call it "date" to match. - // { "time", strlen("time"), Object::DynamicProperty::Time, "QTime", strlen("QTime") }, - // { "date", strlen("date"), Object::DynamicProperty::Date, "QDate", strlen("QDate") }, - { "date", strlen("date"), Object::DynamicProperty::DateTime, "QDateTime", strlen("QDateTime") }, - { "variant", strlen("variant"), Object::DynamicProperty::Variant, "QVariant", strlen("QVariant") }, - { "var", strlen("var"), Object::DynamicProperty::Var, "QVariant", strlen("QVariant") } + // { "time", strlen("time"), Object::DynamicProperty::Time }, + // { "date", strlen("date"), Object::DynamicProperty::Date }, + { "date", strlen("date"), Object::DynamicProperty::DateTime }, + { "variant", strlen("variant"), Object::DynamicProperty::Variant }, + { "var", strlen("var"), Object::DynamicProperty::Var } }; static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) / sizeof(propTypeNameToTypes[0]); @@ -957,7 +952,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node) p = node->parameters; if (paramLength) { - signal->parameterTypes = _parser->_pool.NewRawList<QHashedCStringRef>(paramLength); + signal->parameterTypes = _parser->_pool.NewRawList<Object::DynamicProperty::Type>(paramLength); signal->parameterNames = _parser->_pool.NewRawList<QHashedStringRef>(paramLength); } @@ -984,7 +979,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node) return false; } - signal->parameterTypes[index] = QHashedCStringRef(type->qtName, type->qtNameLength); + signal->parameterTypes[index] = type->type; signal->parameterNames[index] = QHashedStringRef(p->name); p = p->next; index++; diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h index ddf4c9a392..8705f2aef9 100644 --- a/src/qml/qml/qqmlscript_p.h +++ b/src/qml/qml/qqmlscript_p.h @@ -406,10 +406,8 @@ public: DynamicProperty *nextProperty; // Used by the compiler - QByteArray *resolvedCustomTypeName; - QFastMetaBuilder::StringRef typeRef; QFastMetaBuilder::StringRef nameRef; - QFastMetaBuilder::StringRef changedSignatureRef; + QFastMetaBuilder::StringRef changedNameRef; }; struct DynamicSignal : public QQmlPool::POD @@ -417,18 +415,15 @@ public: DynamicSignal(); QHashedStringRef name; - QQmlPool::List<QHashedCStringRef> parameterTypes; + QQmlPool::List<DynamicProperty::Type> parameterTypes; QQmlPool::List<QHashedStringRef> parameterNames; - int parameterTypesLength() const; - int parameterNamesLength() const; - // Used by Object::DynamicSignalList DynamicSignal *nextSignal; // Used by the compiler - QFastMetaBuilder::StringRef signatureRef; - QFastMetaBuilder::StringRef parameterNamesRef; + QFastMetaBuilder::StringRef nameRef; + QQmlPool::List<QFastMetaBuilder::StringRef> parameterNamesRef; LocationSpan location; }; @@ -447,8 +442,8 @@ public: DynamicSlot *nextSlot; // Used by the compiler - QFastMetaBuilder::StringRef signatureRef; - QFastMetaBuilder::StringRef parameterNamesRef; + QFastMetaBuilder::StringRef nameRef; + QQmlPool::List<QFastMetaBuilder::StringRef> parameterNamesRef; }; // The list of dynamic properties @@ -461,6 +456,9 @@ public: typedef QFieldList<DynamicSlot, &DynamicSlot::nextSlot> DynamicSlotList; DynamicSlotList dynamicSlots; + int aggregateDynamicSignalParameterCount() const; + int aggregateDynamicSlotParameterCount() const; + // Used by compiler QQmlCompilerTypes::ComponentCompileState *componentCompileState; diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp index 82f4f7db03..04b63ea7cd 100644 --- a/src/qml/qml/qqmlstringconverters.cpp +++ b/src/qml/qml/qqmlstringconverters.cpp @@ -40,10 +40,9 @@ ****************************************************************************/ #include "qqmlstringconverters_p.h" +#include <private/qqmlglobal_p.h> +#include <private/qqmlinstruction_p.h> -#include <QtGui/qcolor.h> -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> #include <QtCore/qpoint.h> #include <QtCore/qrect.h> #include <QtCore/qsize.h> @@ -52,52 +51,20 @@ QT_BEGIN_NAMESPACE -static uchar fromHex(const uchar c, const uchar c2) -{ - uchar rv = 0; - if (c >= '0' && c <= '9') - rv += (c - '0') * 16; - else if (c >= 'A' && c <= 'F') - rv += (c - 'A' + 10) * 16; - else if (c >= 'a' && c <= 'f') - rv += (c - 'a' + 10) * 16; - - if (c2 >= '0' && c2 <= '9') - rv += (c2 - '0'); - else if (c2 >= 'A' && c2 <= 'F') - rv += (c2 - 'A' + 10); - else if (c2 >= 'a' && c2 <= 'f') - rv += (c2 - 'a' + 10); - - return rv; -} - -static uchar fromHex(const QString &s, int idx) -{ - uchar c = s.at(idx).toAscii(); - uchar c2 = s.at(idx + 1).toAscii(); - return fromHex(c, c2); -} - QVariant QQmlStringConverters::variantFromString(const QString &s) { if (s.isEmpty()) return QVariant(s); + bool ok = false; QRectF r = rectFFromString(s, &ok); if (ok) return QVariant(r); - QColor c = colorFromString(s, &ok); - if (ok) return QVariant(c); QPointF p = pointFFromString(s, &ok); if (ok) return QVariant(p); QSizeF sz = sizeFFromString(s, &ok); if (ok) return QVariant(sz); - QVector3D v = vector3DFromString(s, &ok); - if (ok) return QVariant::fromValue(v); - QVector4D v4 = vector4DFromString(s, &ok); - if (ok) return QVariant::fromValue(v4); - return QVariant(s); + return QQml_valueTypeProvider()->createVariantFromString(s); } QVariant QQmlStringConverters::variantFromString(const QString &s, int preferredType, bool *ok) @@ -107,8 +74,6 @@ QVariant QQmlStringConverters::variantFromString(const QString &s, int preferred return QVariant(int(qRound(s.toDouble(ok)))); case QMetaType::UInt: return QVariant(uint(qRound(s.toDouble(ok)))); - case QMetaType::QColor: - return QVariant::fromValue(colorFromString(s, ok)); #ifndef QT_NO_DATESTRING case QMetaType::QDate: return QVariant::fromValue(dateFromString(s, ok)); @@ -129,30 +94,19 @@ QVariant QQmlStringConverters::variantFromString(const QString &s, int preferred return QVariant::fromValue(rectFFromString(s, ok)); case QMetaType::QRect: return QVariant::fromValue(rectFFromString(s, ok).toRect()); - case QMetaType::QVector3D: - return QVariant::fromValue(vector3DFromString(s, ok)); - case QMetaType::QVector4D: - return QVariant::fromValue(vector4DFromString(s, ok)); default: - if (ok) *ok = false; - return QVariant(); + return QQml_valueTypeProvider()->createVariantFromString(preferredType, s, ok); } } -QColor QQmlStringConverters::colorFromString(const QString &s, bool *ok) +QVariant QQmlStringConverters::colorFromString(const QString &s, bool *ok) { - if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) { - uchar a = fromHex(s, 1); - uchar r = fromHex(s, 3); - uchar g = fromHex(s, 5); - uchar b = fromHex(s, 7); - if (ok) *ok = true; - return QColor(r, g, b, a); - } else { - QColor rv(s); - if (ok) *ok = rv.isValid(); - return rv; - } + return QQml_colorProvider()->colorFromString(s, ok); +} + +unsigned QQmlStringConverters::rgbaFromString(const QString &s, bool *ok) +{ + return QQml_colorProvider()->rgbaFromString(s, ok); } #ifndef QT_NO_DATESTRING @@ -257,58 +211,95 @@ QRectF QQmlStringConverters::rectFFromString(const QString &s, bool *ok) return QRectF(x, y, width, height); } -//expects input of "x,y,z" -QVector3D QQmlStringConverters::vector3DFromString(const QString &s, bool *ok) +bool QQmlStringConverters::createFromString(int type, const QString &s, void *data, size_t n) { - if (s.count(QLatin1Char(',')) != 2) { - if (ok) - *ok = false; - return QVector3D(); - } - - bool xGood, yGood, zGood; - int index = s.indexOf(QLatin1Char(',')); - int index2 = s.indexOf(QLatin1Char(','), index+1); - qreal xCoord = s.left(index).toDouble(&xGood); - qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood); - qreal zCoord = s.mid(index2+1).toDouble(&zGood); - if (!xGood || !yGood || !zGood) { - if (ok) - *ok = false; - return QVector3D(); - } - - if (ok) - *ok = true; - return QVector3D(xCoord, yCoord, zCoord); -} + Q_ASSERT(data); -//expects input of "x,y,z,w" -QVector4D QQmlStringConverters::vector4DFromString(const QString &s, bool *ok) -{ - if (s.count(QLatin1Char(',')) != 3) { - if (ok) - *ok = false; - return QVector4D(); - } + bool ok = false; - bool xGood, yGood, zGood, wGood; - int index = s.indexOf(QLatin1Char(',')); - int index2 = s.indexOf(QLatin1Char(','), index+1); - int index3 = s.indexOf(QLatin1Char(','), index2+1); - qreal xCoord = s.left(index).toDouble(&xGood); - qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood); - qreal zCoord = s.mid(index2+1, index3-index2-1).toDouble(&zGood); - qreal wCoord = s.mid(index3+1).toDouble(&wGood); - if (!xGood || !yGood || !zGood || !wGood) { - if (ok) - *ok = false; - return QVector4D(); + switch (type) { + case QMetaType::Int: + { + Q_ASSERT(n >= sizeof(int)); + int *p = reinterpret_cast<int *>(data); + *p = int(qRound(s.toDouble(&ok))); + return ok; + } + case QMetaType::UInt: + { + Q_ASSERT(n >= sizeof(uint)); + uint *p = reinterpret_cast<uint *>(data); + *p = uint(qRound(s.toDouble(&ok))); + return ok; + } +#ifndef QT_NO_DATESTRING + case QMetaType::QDate: + { + Q_ASSERT(n >= sizeof(QDate)); + QDate *p = reinterpret_cast<QDate *>(data); + *p = dateFromString(s, &ok); + return ok; + } + case QMetaType::QTime: + { + Q_ASSERT(n >= sizeof(QTime)); + QTime *p = reinterpret_cast<QTime *>(data); + *p = timeFromString(s, &ok); + return ok; + } + case QMetaType::QDateTime: + { + Q_ASSERT(n >= sizeof(QDateTime)); + QDateTime *p = reinterpret_cast<QDateTime *>(data); + *p = dateTimeFromString(s, &ok); + return ok; + } +#endif // QT_NO_DATESTRING + case QMetaType::QPointF: + { + Q_ASSERT(n >= sizeof(QPointF)); + QPointF *p = reinterpret_cast<QPointF *>(data); + *p = pointFFromString(s, &ok); + return ok; + } + case QMetaType::QPoint: + { + Q_ASSERT(n >= sizeof(QPoint)); + QPoint *p = reinterpret_cast<QPoint *>(data); + *p = pointFFromString(s, &ok).toPoint(); + return ok; + } + case QMetaType::QSizeF: + { + Q_ASSERT(n >= sizeof(QSizeF)); + QSizeF *p = reinterpret_cast<QSizeF *>(data); + *p = sizeFFromString(s, &ok); + return ok; + } + case QMetaType::QSize: + { + Q_ASSERT(n >= sizeof(QSize)); + QSize *p = reinterpret_cast<QSize *>(data); + *p = sizeFFromString(s, &ok).toSize(); + return ok; + } + case QMetaType::QRectF: + { + Q_ASSERT(n >= sizeof(QRectF)); + QRectF *p = reinterpret_cast<QRectF *>(data); + *p = rectFFromString(s, &ok); + return ok; + } + case QMetaType::QRect: + { + Q_ASSERT(n >= sizeof(QRect)); + QRect *p = reinterpret_cast<QRect *>(data); + *p = rectFFromString(s, &ok).toRect(); + return ok; + } + default: + return QQml_valueTypeProvider()->createValueFromString(type, s, data, n); } - - if (ok) - *ok = true; - return QVector4D(xCoord, yCoord, zCoord, wCoord); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlstringconverters_p.h b/src/qml/qml/qqmlstringconverters_p.h index 8f6fb2485d..3e637db83b 100644 --- a/src/qml/qml/qqmlstringconverters_p.h +++ b/src/qml/qml/qqmlstringconverters_p.h @@ -60,32 +60,31 @@ QT_BEGIN_NAMESPACE -class QColor; class QPointF; class QSizeF; class QRectF; class QString; class QByteArray; -class QVector3D; -class QVector4D; // XXX - Bauhaus currently uses these methods which is why they're exported namespace QQmlStringConverters { - QVariant Q_QML_PRIVATE_EXPORT variantFromString(const QString &); - QVariant Q_QML_PRIVATE_EXPORT variantFromString(const QString &, int preferredType, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &); + Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &, int preferredType, bool *ok = 0); + + Q_QML_PRIVATE_EXPORT QVariant colorFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT unsigned rgbaFromString(const QString &, bool *ok = 0); - QColor Q_QML_PRIVATE_EXPORT colorFromString(const QString &, bool *ok = 0); #ifndef QT_NO_DATESTRING - QDate Q_QML_PRIVATE_EXPORT dateFromString(const QString &, bool *ok = 0); - QTime Q_QML_PRIVATE_EXPORT timeFromString(const QString &, bool *ok = 0); - QDateTime Q_QML_PRIVATE_EXPORT dateTimeFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QDate dateFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QTime timeFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QDateTime dateTimeFromString(const QString &, bool *ok = 0); #endif - QPointF Q_QML_PRIVATE_EXPORT pointFFromString(const QString &, bool *ok = 0); - QSizeF Q_QML_PRIVATE_EXPORT sizeFFromString(const QString &, bool *ok = 0); - QRectF Q_QML_PRIVATE_EXPORT rectFFromString(const QString &, bool *ok = 0); - QVector3D Q_QML_PRIVATE_EXPORT vector3DFromString(const QString &, bool *ok = 0); - QVector4D Q_QML_PRIVATE_EXPORT vector4DFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QPointF pointFFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QSizeF sizeFFromString(const QString &, bool *ok = 0); + Q_QML_PRIVATE_EXPORT QRectF rectFFromString(const QString &, bool *ok = 0); + + Q_QML_PRIVATE_EXPORT bool createFromString(int, const QString &, void *, size_t); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 4ade00f9b4..fdc44c22be 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -40,48 +40,17 @@ ****************************************************************************/ #include "qqmlvaluetype_p.h" - #include "qqmlmetatype_p.h" -#include <private/qfont_p.h> +#include <private/qqmlglobal_p.h> #include <QtCore/qdebug.h> QT_BEGIN_NAMESPACE -template<typename T> -int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMinor, const char *qmlName) -{ - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - - QQmlPrivate::RegisterType type = { - 0, - - qRegisterMetaType<T *>(pointerName.constData()), 0, 0, 0, - - QString(), - - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, - - 0, 0, - - 0, 0, 0, - - 0, 0, - - 0, - 0 - }; - - return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); -} - QQmlValueTypeFactory::QQmlValueTypeFactory() { - // ### Optimize for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii) - valueTypes[ii] = valueType(ii); + valueTypes[ii] = 0; } QQmlValueTypeFactory::~QQmlValueTypeFactory() @@ -106,7 +75,6 @@ bool QQmlValueTypeFactory::isValueType(int idx) void QQmlValueTypeFactory::registerBaseTypes(const char *uri, int versionMajor, int versionMinor) { qmlRegisterValueTypeEnums<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing"); - qmlRegisterValueTypeEnums<QQmlFontValueType>(uri, versionMajor, versionMinor, "Font"); } void QQmlValueTypeFactory::registerValueTypes() @@ -137,31 +105,11 @@ QQmlValueType *QQmlValueTypeFactory::valueType(int t) case QVariant::RectF: rv = new QQmlRectFValueType; break; - case QVariant::Vector2D: - rv = new QQmlVector2DValueType; - break; - case QVariant::Vector3D: - rv = new QQmlVector3DValueType; - break; - case QVariant::Vector4D: - rv = new QQmlVector4DValueType; - break; - case QVariant::Quaternion: - rv = new QQmlQuaternionValueType; - break; - case QVariant::Matrix4x4: - rv = new QQmlMatrix4x4ValueType; - break; case QVariant::EasingCurve: rv = new QQmlEasingValueType; break; - case QVariant::Font: - rv = new QQmlFontValueType; - break; - case QVariant::Color: - rv = new QQmlColorValueType; - break; default: + rv = QQml_valueTypeProvider()->createValueType(t); break; } @@ -174,445 +122,281 @@ QQmlValueType::QQmlValueType(QObject *parent) { } -#define QML_VALUETYPE_READWRITE(name, cpptype, var) \ - QQml ## name ## ValueType::QQml ## name ## ValueType(QObject *parent) \ - : QQmlValueType(parent) \ - { \ - } \ - void QQml ## name ## ValueType::read(QObject *obj, int idx) \ - { \ - void *a[] = { &var, 0 }; \ - QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); \ - onLoad(); \ - } \ - void QQml ## name ## ValueType::write(QObject *obj, int idx, \ - QQmlPropertyPrivate::WriteFlags flags) \ - { \ - int status = -1; \ - void *a[] = { &var, 0, &status, &flags }; \ - QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); \ - } \ - bool QQml ## name ## ValueType::isEqual(const QVariant &value) const \ - { \ - return QVariant(var) == value; \ - } \ - QVariant QQml ## name ## ValueType::value() \ - { \ - return QVariant(var); \ - } \ - void QQml ## name ## ValueType::setValue(const QVariant &value) \ - { \ - var = qvariant_cast<cpptype>(value); \ - onLoad(); \ - } -QML_VALUETYPE_READWRITE(PointF, QPointF, point); -QML_VALUETYPE_READWRITE(Point, QPoint, point); -QML_VALUETYPE_READWRITE(SizeF, QSizeF, size); -QML_VALUETYPE_READWRITE(Size, QSize, size); -QML_VALUETYPE_READWRITE(RectF, QRectF, rect); -QML_VALUETYPE_READWRITE(Rect, QRect, rect); -QML_VALUETYPE_READWRITE(Vector2D, QVector2D, vector); -QML_VALUETYPE_READWRITE(Vector3D, QVector3D, vector); -QML_VALUETYPE_READWRITE(Vector4D, QVector4D, vector); -QML_VALUETYPE_READWRITE(Quaternion, QQuaternion, quaternion); -QML_VALUETYPE_READWRITE(Matrix4x4, QMatrix4x4, matrix); -QML_VALUETYPE_READWRITE(Easing, QEasingCurve, easing); -QML_VALUETYPE_READWRITE(Font, QFont, font); -QML_VALUETYPE_READWRITE(Color, QColor, color); +QQmlPointFValueType::QQmlPointFValueType(QObject *parent) + : QQmlValueTypeBase<QPointF>(parent) +{ +} QString QQmlPointFValueType::toString() const { - return QString(QLatin1String("QPointF(%1, %2)")).arg(point.x()).arg(point.y()); + return QString(QLatin1String("QPointF(%1, %2)")).arg(v.x()).arg(v.y()); } qreal QQmlPointFValueType::x() const { - return point.x(); + return v.x(); } qreal QQmlPointFValueType::y() const { - return point.y(); + return v.y(); } void QQmlPointFValueType::setX(qreal x) { - point.setX(x); + v.setX(x); } void QQmlPointFValueType::setY(qreal y) { - point.setY(y); + v.setY(y); +} + + +QQmlPointValueType::QQmlPointValueType(QObject *parent) + : QQmlValueTypeBase<QPoint>(parent) +{ } QString QQmlPointValueType::toString() const { - return QString(QLatin1String("QPoint(%1, %2)")).arg(point.x()).arg(point.y()); + return QString(QLatin1String("QPoint(%1, %2)")).arg(v.x()).arg(v.y()); } int QQmlPointValueType::x() const { - return point.x(); + return v.x(); } int QQmlPointValueType::y() const { - return point.y(); + return v.y(); } void QQmlPointValueType::setX(int x) { - point.setX(x); + v.setX(x); } void QQmlPointValueType::setY(int y) { - point.setY(y); + v.setY(y); +} + + +QQmlSizeFValueType::QQmlSizeFValueType(QObject *parent) + : QQmlValueTypeBase<QSizeF>(parent) +{ } QString QQmlSizeFValueType::toString() const { - return QString(QLatin1String("QSizeF(%1, %2)")).arg(size.width()).arg(size.height()); + return QString(QLatin1String("QSizeF(%1, %2)")).arg(v.width()).arg(v.height()); } qreal QQmlSizeFValueType::width() const { - return size.width(); + return v.width(); } qreal QQmlSizeFValueType::height() const { - return size.height(); + return v.height(); } void QQmlSizeFValueType::setWidth(qreal w) { - size.setWidth(w); + v.setWidth(w); } void QQmlSizeFValueType::setHeight(qreal h) { - size.setHeight(h); + v.setHeight(h); +} + + +QQmlSizeValueType::QQmlSizeValueType(QObject *parent) + : QQmlValueTypeBase<QSize>(parent) +{ } QString QQmlSizeValueType::toString() const { - return QString(QLatin1String("QSize(%1, %2)")).arg(size.width()).arg(size.height()); + return QString(QLatin1String("QSize(%1, %2)")).arg(v.width()).arg(v.height()); } int QQmlSizeValueType::width() const { - return size.width(); + return v.width(); } int QQmlSizeValueType::height() const { - return size.height(); + return v.height(); } void QQmlSizeValueType::setWidth(int w) { - size.setWidth(w); + v.setWidth(w); } void QQmlSizeValueType::setHeight(int h) { - size.setHeight(h); + v.setHeight(h); +} + + +QQmlRectFValueType::QQmlRectFValueType(QObject *parent) + : QQmlValueTypeBase<QRectF>(parent) +{ } QString QQmlRectFValueType::toString() const { - return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height()); + return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height()); } qreal QQmlRectFValueType::x() const { - return rect.x(); + return v.x(); } qreal QQmlRectFValueType::y() const { - return rect.y(); + return v.y(); } void QQmlRectFValueType::setX(qreal x) { - rect.moveLeft(x); + v.moveLeft(x); } void QQmlRectFValueType::setY(qreal y) { - rect.moveTop(y); + v.moveTop(y); } qreal QQmlRectFValueType::width() const { - return rect.width(); + return v.width(); } qreal QQmlRectFValueType::height() const { - return rect.height(); + return v.height(); } void QQmlRectFValueType::setWidth(qreal w) { - rect.setWidth(w); + v.setWidth(w); } void QQmlRectFValueType::setHeight(qreal h) { - rect.setHeight(h); + v.setHeight(h); +} + + +QQmlRectValueType::QQmlRectValueType(QObject *parent) + : QQmlValueTypeBase<QRect>(parent) +{ } QString QQmlRectValueType::toString() const { - return QString(QLatin1String("QRect(%1, %2, %3, %4)")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height()); + return QString(QLatin1String("QRect(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height()); } int QQmlRectValueType::x() const { - return rect.x(); + return v.x(); } int QQmlRectValueType::y() const { - return rect.y(); + return v.y(); } void QQmlRectValueType::setX(int x) { - rect.moveLeft(x); + v.moveLeft(x); } void QQmlRectValueType::setY(int y) { - rect.moveTop(y); + v.moveTop(y); } int QQmlRectValueType::width() const { - return rect.width(); + return v.width(); } int QQmlRectValueType::height() const { - return rect.height(); + return v.height(); } void QQmlRectValueType::setWidth(int w) { - rect.setWidth(w); + v.setWidth(w); } void QQmlRectValueType::setHeight(int h) { - rect.setHeight(h); + v.setHeight(h); } -QString QQmlVector2DValueType::toString() const -{ - return QString(QLatin1String("QVector2D(%1, %2)")).arg(vector.x()).arg(vector.y()); -} -qreal QQmlVector2DValueType::x() const +QQmlEasingValueType::QQmlEasingValueType(QObject *parent) + : QQmlValueTypeBase<QEasingCurve>(parent) { - return vector.x(); -} - -qreal QQmlVector2DValueType::y() const -{ - return vector.y(); -} - -void QQmlVector2DValueType::setX(qreal x) -{ - vector.setX(x); -} - -void QQmlVector2DValueType::setY(qreal y) -{ - vector.setY(y); -} - -QString QQmlVector3DValueType::toString() const -{ - return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(vector.x()).arg(vector.y()).arg(vector.z()); -} - -qreal QQmlVector3DValueType::x() const -{ - return vector.x(); -} - -qreal QQmlVector3DValueType::y() const -{ - return vector.y(); -} - -qreal QQmlVector3DValueType::z() const -{ - return vector.z(); -} - -void QQmlVector3DValueType::setX(qreal x) -{ - vector.setX(x); -} - -void QQmlVector3DValueType::setY(qreal y) -{ - vector.setY(y); -} - -void QQmlVector3DValueType::setZ(qreal z) -{ - vector.setZ(z); -} - -QString QQmlVector4DValueType::toString() const -{ - return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(vector.x()).arg(vector.y()).arg(vector.z()).arg(vector.w()); -} - -qreal QQmlVector4DValueType::x() const -{ - return vector.x(); -} - -qreal QQmlVector4DValueType::y() const -{ - return vector.y(); -} - -qreal QQmlVector4DValueType::z() const -{ - return vector.z(); -} - -qreal QQmlVector4DValueType::w() const -{ - return vector.w(); -} - -void QQmlVector4DValueType::setX(qreal x) -{ - vector.setX(x); -} - -void QQmlVector4DValueType::setY(qreal y) -{ - vector.setY(y); -} - -void QQmlVector4DValueType::setZ(qreal z) -{ - vector.setZ(z); -} - -void QQmlVector4DValueType::setW(qreal w) -{ - vector.setW(w); -} - -QString QQmlQuaternionValueType::toString() const -{ - return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(quaternion.scalar()).arg(quaternion.x()).arg(quaternion.y()).arg(quaternion.z()); -} - -qreal QQmlQuaternionValueType::scalar() const -{ - return quaternion.scalar(); -} - -qreal QQmlQuaternionValueType::x() const -{ - return quaternion.x(); -} - -qreal QQmlQuaternionValueType::y() const -{ - return quaternion.y(); -} - -qreal QQmlQuaternionValueType::z() const -{ - return quaternion.z(); -} - -void QQmlQuaternionValueType::setScalar(qreal scalar) -{ - quaternion.setScalar(scalar); -} - -void QQmlQuaternionValueType::setX(qreal x) -{ - quaternion.setX(x); -} - -void QQmlQuaternionValueType::setY(qreal y) -{ - quaternion.setY(y); -} - -void QQmlQuaternionValueType::setZ(qreal z) -{ - quaternion.setZ(z); -} - -QString QQmlMatrix4x4ValueType::toString() const -{ - return QString(QLatin1String("QMatrix4x4(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16)")) - .arg(matrix(0, 0)).arg(matrix(0, 1)).arg(matrix(0, 2)).arg(matrix(0, 3)) - .arg(matrix(1, 0)).arg(matrix(1, 1)).arg(matrix(1, 2)).arg(matrix(1, 3)) - .arg(matrix(2, 0)).arg(matrix(2, 1)).arg(matrix(2, 2)).arg(matrix(2, 3)) - .arg(matrix(3, 0)).arg(matrix(3, 1)).arg(matrix(3, 2)).arg(matrix(3, 3)); } QString QQmlEasingValueType::toString() const { - return QString(QLatin1String("QEasingCurve(%1, %2, %3, %4)")).arg(easing.type()).arg(easing.amplitude()).arg(easing.overshoot()).arg(easing.period()); + return QString(QLatin1String("QEasingCurve(%1, %2, %3, %4)")).arg(v.type()).arg(v.amplitude()).arg(v.overshoot()).arg(v.period()); } QQmlEasingValueType::Type QQmlEasingValueType::type() const { - return (QQmlEasingValueType::Type)easing.type(); + return (QQmlEasingValueType::Type)v.type(); } qreal QQmlEasingValueType::amplitude() const { - return easing.amplitude(); + return v.amplitude(); } qreal QQmlEasingValueType::overshoot() const { - return easing.overshoot(); + return v.overshoot(); } qreal QQmlEasingValueType::period() const { - return easing.period(); + return v.period(); } void QQmlEasingValueType::setType(QQmlEasingValueType::Type type) { - easing.setType((QEasingCurve::Type)type); + v.setType((QEasingCurve::Type)type); } void QQmlEasingValueType::setAmplitude(qreal amplitude) { - easing.setAmplitude(amplitude); + v.setAmplitude(amplitude); } void QQmlEasingValueType::setOvershoot(qreal overshoot) { - easing.setOvershoot(overshoot); + v.setOvershoot(overshoot); } void QQmlEasingValueType::setPeriod(qreal period) { - easing.setPeriod(period); + v.setPeriod(period); } void QQmlEasingValueType::setBezierCurve(const QVariantList &customCurveVariant) @@ -646,7 +430,7 @@ void QQmlEasingValueType::setBezierCurve(const QVariantList &customCurveVariant) const QPointF c3(c3x, c3y); newEasingCurve.addCubicBezierSegment(c1, c2, c3); - easing = newEasingCurve; + v = newEasingCurve; } } } @@ -655,214 +439,10 @@ void QQmlEasingValueType::setBezierCurve(const QVariantList &customCurveVariant) QVariantList QQmlEasingValueType::bezierCurve() const { QVariantList rv; - QList<QPointF> points = easing.cubicBezierSpline(); + QList<QPointF> points = v.cubicBezierSpline(); for (int ii = 0; ii < points.count(); ++ii) rv << QVariant(points.at(ii).x()) << QVariant(points.at(ii).y()); return rv; } -void QQmlFontValueType::onLoad() -{ - pixelSizeSet = false; - pointSizeSet = false; -} - -QString QQmlFontValueType::toString() const -{ - return QString(QLatin1String("QFont(%1)")).arg(font.toString()); -} - -QString QQmlFontValueType::family() const -{ - return font.family(); -} - -void QQmlFontValueType::setFamily(const QString &family) -{ - font.setFamily(family); -} - -bool QQmlFontValueType::bold() const -{ - return font.bold(); -} - -void QQmlFontValueType::setBold(bool b) -{ - font.setBold(b); -} - -QQmlFontValueType::FontWeight QQmlFontValueType::weight() const -{ - return (QQmlFontValueType::FontWeight)font.weight(); -} - -void QQmlFontValueType::setWeight(QQmlFontValueType::FontWeight w) -{ - font.setWeight((QFont::Weight)w); -} - -bool QQmlFontValueType::italic() const -{ - return font.italic(); -} - -void QQmlFontValueType::setItalic(bool b) -{ - font.setItalic(b); -} - -bool QQmlFontValueType::underline() const -{ - return font.underline(); -} - -void QQmlFontValueType::setUnderline(bool b) -{ - font.setUnderline(b); -} - -bool QQmlFontValueType::overline() const -{ - return font.overline(); -} - -void QQmlFontValueType::setOverline(bool b) -{ - font.setOverline(b); -} - -bool QQmlFontValueType::strikeout() const -{ - return font.strikeOut(); -} - -void QQmlFontValueType::setStrikeout(bool b) -{ - font.setStrikeOut(b); -} - -qreal QQmlFontValueType::pointSize() const -{ - if (font.pointSizeF() == -1) { - if (dpi.isNull) - dpi = qt_defaultDpi(); - return font.pixelSize() * qreal(72.) / qreal(dpi); - } - return font.pointSizeF(); -} - -void QQmlFontValueType::setPointSize(qreal size) -{ - if (pixelSizeSet) { - qWarning() << "Both point size and pixel size set. Using pixel size."; - return; - } - - if (size >= 0.0) { - pointSizeSet = true; - font.setPointSizeF(size); - } else { - pointSizeSet = false; - } -} - -int QQmlFontValueType::pixelSize() const -{ - if (font.pixelSize() == -1) { - if (dpi.isNull) - dpi = qt_defaultDpi(); - return (font.pointSizeF() * dpi) / qreal(72.); - } - return font.pixelSize(); -} - -void QQmlFontValueType::setPixelSize(int size) -{ - if (size >0) { - if (pointSizeSet) - qWarning() << "Both point size and pixel size set. Using pixel size."; - font.setPixelSize(size); - pixelSizeSet = true; - } else { - pixelSizeSet = false; - } -} - -QQmlFontValueType::Capitalization QQmlFontValueType::capitalization() const -{ - return (QQmlFontValueType::Capitalization)font.capitalization(); -} - -void QQmlFontValueType::setCapitalization(QQmlFontValueType::Capitalization c) -{ - font.setCapitalization((QFont::Capitalization)c); -} - -qreal QQmlFontValueType::letterSpacing() const -{ - return font.letterSpacing(); -} - -void QQmlFontValueType::setLetterSpacing(qreal size) -{ - font.setLetterSpacing(QFont::AbsoluteSpacing, size); -} - -qreal QQmlFontValueType::wordSpacing() const -{ - return font.wordSpacing(); -} - -void QQmlFontValueType::setWordSpacing(qreal size) -{ - font.setWordSpacing(size); -} - -QString QQmlColorValueType::toString() const -{ - // special case - to maintain behaviour with QtQuick 1.0, we just output normal toString() value. - return QVariant(color).toString(); -} - -qreal QQmlColorValueType::r() const -{ - return color.redF(); -} - -qreal QQmlColorValueType::g() const -{ - return color.greenF(); -} - -qreal QQmlColorValueType::b() const -{ - return color.blueF(); -} - -qreal QQmlColorValueType::a() const -{ - return color.alphaF(); -} - -void QQmlColorValueType::setR(qreal r) -{ - color.setRedF(r); -} - -void QQmlColorValueType::setG(qreal g) -{ - color.setGreenF(g); -} - -void QQmlColorValueType::setB(qreal b) -{ - color.setBlueF(b); -} - -void QQmlColorValueType::setA(qreal a) -{ - color.setAlphaF(a); -} - QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 71817c2a2d..d55c839c7d 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -53,6 +53,7 @@ // We mean it. // +#include "qqml.h" #include "qqmlproperty.h" #include "qqmlproperty_p.h" #include "qqmlnullablevalue_p_p.h" @@ -61,13 +62,6 @@ #include <QtCore/qrect.h> #include <QtCore/qeasingcurve.h> #include <QtCore/qvariant.h> -#include <QtGui/qvector2d.h> -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> -#include <QtGui/qmatrix4x4.h> -#include <QtGui/qquaternion.h> -#include <QtGui/qfont.h> -#include <QtGui/qcolor.h> QT_BEGIN_NAMESPACE @@ -84,7 +78,63 @@ public: virtual QString toString() const = 0; virtual bool isEqual(const QVariant &value) const = 0; - inline void onLoad(); + virtual void onLoad() {} + +protected: + inline void readProperty(QObject *obj, int idx, void *p) + { + void *a[] = { p, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); + onLoad(); + } + + inline void writeProperty(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, void *p) + { + int status = -1; + void *a[] = { p, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); + } +}; + +template <typename T> +class QQmlValueTypeBase : public QQmlValueType +{ +public: + typedef T ValueType; + + QQmlValueTypeBase(QObject *parent) + : QQmlValueType(parent) + { + } + + virtual void read(QObject *obj, int idx) + { + readProperty(obj, idx, &v); + } + + virtual void write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags) + { + writeProperty(obj, idx, flags, &v); + } + + virtual QVariant value() + { + return QVariant(v); + } + + virtual void setValue(const QVariant &value) + { + v = qvariant_cast<T>(value); + onLoad(); + } + + virtual bool isEqual(const QVariant &other) const + { + return QVariant(v) == other; + } + +protected: + ValueType v; }; class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory @@ -99,16 +149,27 @@ public: static void registerValueTypes(); QQmlValueType *operator[](int idx) const { - if (idx >= (int)QVariant::UserType) return 0; - else return valueTypes[idx]; + if (idx >= (int)QVariant::UserType) + return 0; + + QQmlValueType *rv = valueTypes[idx]; + if (!rv) { + // Table update is not thread-safe, but the potential for leaks is + // so small that the cost of protection is unwarranted + if ((rv = valueType(idx))) { + valueTypes[idx] = rv; + } + } + return rv; } private: - QQmlValueType *valueTypes[QVariant::UserType - 1]; + mutable QQmlValueType *valueTypes[QVariant::UserType - 1]; }; -// Exported for QtQuick1 -class Q_QML_PRIVATE_EXPORT QQmlPointFValueType : public QQmlValueType +// These exports of these value types are obsolete since QtQuick1 no longer +// needs them - they should become Q_AUTOTEST_EXPORT +class Q_QML_PRIVATE_EXPORT QQmlPointFValueType : public QQmlValueTypeBase<QPointF> { Q_PROPERTY(qreal x READ x WRITE setX) Q_PROPERTY(qreal y READ y WRITE setY) @@ -116,24 +177,15 @@ class Q_QML_PRIVATE_EXPORT QQmlPointFValueType : public QQmlValueType public: QQmlPointFValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; qreal x() const; qreal y() const; void setX(qreal); void setY(qreal); - -private: - QPointF point; }; -// Exported for QtQuick1 -class Q_QML_PRIVATE_EXPORT QQmlPointValueType : public QQmlValueType +class Q_QML_PRIVATE_EXPORT QQmlPointValueType : public QQmlValueTypeBase<QPoint> { Q_PROPERTY(int x READ x WRITE setX) Q_PROPERTY(int y READ y WRITE setY) @@ -141,24 +193,15 @@ class Q_QML_PRIVATE_EXPORT QQmlPointValueType : public QQmlValueType public: QQmlPointValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; int x() const; int y() const; void setX(int); void setY(int); - -private: - QPoint point; }; -// Exported for QtQuick1 -class Q_QML_PRIVATE_EXPORT QQmlSizeFValueType : public QQmlValueType +class Q_QML_PRIVATE_EXPORT QQmlSizeFValueType : public QQmlValueTypeBase<QSizeF> { Q_PROPERTY(qreal width READ width WRITE setWidth) Q_PROPERTY(qreal height READ height WRITE setHeight) @@ -166,24 +209,15 @@ class Q_QML_PRIVATE_EXPORT QQmlSizeFValueType : public QQmlValueType public: QQmlSizeFValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; qreal width() const; qreal height() const; void setWidth(qreal); void setHeight(qreal); - -private: - QSizeF size; }; -// Exported for QtQuick1 -class Q_QML_PRIVATE_EXPORT QQmlSizeValueType : public QQmlValueType +class Q_QML_PRIVATE_EXPORT QQmlSizeValueType : public QQmlValueTypeBase<QSize> { Q_PROPERTY(int width READ width WRITE setWidth) Q_PROPERTY(int height READ height WRITE setHeight) @@ -191,24 +225,15 @@ class Q_QML_PRIVATE_EXPORT QQmlSizeValueType : public QQmlValueType public: QQmlSizeValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; int width() const; int height() const; void setWidth(int); void setHeight(int); - -private: - QSize size; }; -// Exported for QtQuick1 -class Q_QML_PRIVATE_EXPORT QQmlRectFValueType : public QQmlValueType +class Q_QML_PRIVATE_EXPORT QQmlRectFValueType : public QQmlValueTypeBase<QRectF> { Q_PROPERTY(qreal x READ x WRITE setX) Q_PROPERTY(qreal y READ y WRITE setY) @@ -218,12 +243,7 @@ class Q_QML_PRIVATE_EXPORT QQmlRectFValueType : public QQmlValueType public: QQmlRectFValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; qreal x() const; qreal y() const; @@ -234,13 +254,9 @@ public: qreal height() const; void setWidth(qreal); void setHeight(qreal); - -private: - QRectF rect; }; -// Exported for QtQuick1 -class Q_QML_PRIVATE_EXPORT QQmlRectValueType : public QQmlValueType +class Q_QML_PRIVATE_EXPORT QQmlRectValueType : public QQmlValueTypeBase<QRect> { Q_PROPERTY(int x READ x WRITE setX) Q_PROPERTY(int y READ y WRITE setY) @@ -250,12 +266,7 @@ class Q_QML_PRIVATE_EXPORT QQmlRectValueType : public QQmlValueType public: QQmlRectValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; int x() const; int y() const; @@ -266,190 +277,9 @@ public: int height() const; void setWidth(int); void setHeight(int); - -private: - QRect rect; }; -class Q_QML_PRIVATE_EXPORT QQmlVector2DValueType : public QQmlValueType -{ - Q_PROPERTY(qreal x READ x WRITE setX) - Q_PROPERTY(qreal y READ y WRITE setY) - Q_OBJECT -public: - QQmlVector2DValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - qreal x() const; - qreal y() const; - void setX(qreal); - void setY(qreal); - -private: - QVector2D vector; -}; - -class Q_QML_PRIVATE_EXPORT QQmlVector3DValueType : public QQmlValueType -{ - Q_PROPERTY(qreal x READ x WRITE setX) - Q_PROPERTY(qreal y READ y WRITE setY) - Q_PROPERTY(qreal z READ z WRITE setZ) - Q_OBJECT -public: - QQmlVector3DValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - qreal x() const; - qreal y() const; - qreal z() const; - void setX(qreal); - void setY(qreal); - void setZ(qreal); - -private: - QVector3D vector; -}; - -class Q_QML_PRIVATE_EXPORT QQmlVector4DValueType : public QQmlValueType -{ - Q_PROPERTY(qreal x READ x WRITE setX) - Q_PROPERTY(qreal y READ y WRITE setY) - Q_PROPERTY(qreal z READ z WRITE setZ) - Q_PROPERTY(qreal w READ w WRITE setW) - Q_OBJECT -public: - QQmlVector4DValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - qreal x() const; - qreal y() const; - qreal z() const; - qreal w() const; - void setX(qreal); - void setY(qreal); - void setZ(qreal); - void setW(qreal); - -private: - QVector4D vector; -}; - -class Q_QML_PRIVATE_EXPORT QQmlQuaternionValueType : public QQmlValueType -{ - Q_PROPERTY(qreal scalar READ scalar WRITE setScalar) - Q_PROPERTY(qreal x READ x WRITE setX) - Q_PROPERTY(qreal y READ y WRITE setY) - Q_PROPERTY(qreal z READ z WRITE setZ) - Q_OBJECT -public: - QQmlQuaternionValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - qreal scalar() const; - qreal x() const; - qreal y() const; - qreal z() const; - void setScalar(qreal); - void setX(qreal); - void setY(qreal); - void setZ(qreal); - -private: - QQuaternion quaternion; -}; - -class Q_QML_PRIVATE_EXPORT QQmlMatrix4x4ValueType : public QQmlValueType -{ - Q_PROPERTY(qreal m11 READ m11 WRITE setM11) - Q_PROPERTY(qreal m12 READ m12 WRITE setM12) - Q_PROPERTY(qreal m13 READ m13 WRITE setM13) - Q_PROPERTY(qreal m14 READ m14 WRITE setM14) - Q_PROPERTY(qreal m21 READ m21 WRITE setM21) - Q_PROPERTY(qreal m22 READ m22 WRITE setM22) - Q_PROPERTY(qreal m23 READ m23 WRITE setM23) - Q_PROPERTY(qreal m24 READ m24 WRITE setM24) - Q_PROPERTY(qreal m31 READ m31 WRITE setM31) - Q_PROPERTY(qreal m32 READ m32 WRITE setM32) - Q_PROPERTY(qreal m33 READ m33 WRITE setM33) - Q_PROPERTY(qreal m34 READ m34 WRITE setM34) - Q_PROPERTY(qreal m41 READ m41 WRITE setM41) - Q_PROPERTY(qreal m42 READ m42 WRITE setM42) - Q_PROPERTY(qreal m43 READ m43 WRITE setM43) - Q_PROPERTY(qreal m44 READ m44 WRITE setM44) - Q_OBJECT -public: - QQmlMatrix4x4ValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - qreal m11() const { return matrix(0, 0); } - qreal m12() const { return matrix(0, 1); } - qreal m13() const { return matrix(0, 2); } - qreal m14() const { return matrix(0, 3); } - qreal m21() const { return matrix(1, 0); } - qreal m22() const { return matrix(1, 1); } - qreal m23() const { return matrix(1, 2); } - qreal m24() const { return matrix(1, 3); } - qreal m31() const { return matrix(2, 0); } - qreal m32() const { return matrix(2, 1); } - qreal m33() const { return matrix(2, 2); } - qreal m34() const { return matrix(2, 3); } - qreal m41() const { return matrix(3, 0); } - qreal m42() const { return matrix(3, 1); } - qreal m43() const { return matrix(3, 2); } - qreal m44() const { return matrix(3, 3); } - - void setM11(qreal value) { matrix(0, 0) = value; } - void setM12(qreal value) { matrix(0, 1) = value; } - void setM13(qreal value) { matrix(0, 2) = value; } - void setM14(qreal value) { matrix(0, 3) = value; } - void setM21(qreal value) { matrix(1, 0) = value; } - void setM22(qreal value) { matrix(1, 1) = value; } - void setM23(qreal value) { matrix(1, 2) = value; } - void setM24(qreal value) { matrix(1, 3) = value; } - void setM31(qreal value) { matrix(2, 0) = value; } - void setM32(qreal value) { matrix(2, 1) = value; } - void setM33(qreal value) { matrix(2, 2) = value; } - void setM34(qreal value) { matrix(2, 3) = value; } - void setM41(qreal value) { matrix(3, 0) = value; } - void setM42(qreal value) { matrix(3, 1) = value; } - void setM43(qreal value) { matrix(3, 2) = value; } - void setM44(qreal value) { matrix(3, 3) = value; } - -private: - QMatrix4x4 matrix; -}; - -class Q_QML_PRIVATE_EXPORT QQmlEasingValueType : public QQmlValueType +class Q_QML_PRIVATE_EXPORT QQmlEasingValueType : public QQmlValueTypeBase<QEasingCurve> { Q_OBJECT Q_ENUMS(Type) @@ -489,12 +319,7 @@ public: QQmlEasingValueType(QObject *parent = 0); - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; Type type() const; qreal amplitude() const; @@ -506,128 +331,35 @@ public: void setPeriod(qreal); void setBezierCurve(const QVariantList &); QVariantList bezierCurve() const; - - -private: - QEasingCurve easing; }; -class Q_QML_PRIVATE_EXPORT QQmlFontValueType : public QQmlValueType +template<typename T> +int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - Q_OBJECT - Q_ENUMS(FontWeight) - Q_ENUMS(Capitalization) - - Q_PROPERTY(QString family READ family WRITE setFamily) - Q_PROPERTY(bool bold READ bold WRITE setBold) - Q_PROPERTY(FontWeight weight READ weight WRITE setWeight) - Q_PROPERTY(bool italic READ italic WRITE setItalic) - Q_PROPERTY(bool underline READ underline WRITE setUnderline) - Q_PROPERTY(bool overline READ overline WRITE setOverline) - Q_PROPERTY(bool strikeout READ strikeout WRITE setStrikeout) - Q_PROPERTY(qreal pointSize READ pointSize WRITE setPointSize) - Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize) - Q_PROPERTY(Capitalization capitalization READ capitalization WRITE setCapitalization) - Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing) - Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing) - -public: - enum FontWeight { Light = QFont::Light, - Normal = QFont::Normal, - DemiBold = QFont::DemiBold, - Bold = QFont::Bold, - Black = QFont::Black }; - enum Capitalization { MixedCase = QFont::MixedCase, - AllUppercase = QFont::AllUppercase, - AllLowercase = QFont::AllLowercase, - SmallCaps = QFont::SmallCaps, - Capitalize = QFont::Capitalize }; - - QQmlFontValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - QString family() const; - void setFamily(const QString &); - - bool bold() const; - void setBold(bool b); + QByteArray name(T::staticMetaObject.className()); - FontWeight weight() const; - void setWeight(FontWeight); + QByteArray pointerName(name + '*'); - bool italic() const; - void setItalic(bool b); + QQmlPrivate::RegisterType type = { + 0, - bool underline() const; - void setUnderline(bool b); + qRegisterMetaType<T *>(pointerName.constData()), 0, 0, 0, - bool overline() const; - void setOverline(bool b); + QString(), - bool strikeout() const; - void setStrikeout(bool b); + uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, - qreal pointSize() const; - void setPointSize(qreal size); + 0, 0, - int pixelSize() const; - void setPixelSize(int size); + 0, 0, 0, - Capitalization capitalization() const; - void setCapitalization(Capitalization); + 0, 0, - qreal letterSpacing() const; - void setLetterSpacing(qreal spacing); - - qreal wordSpacing() const; - void setWordSpacing(qreal spacing); - - void onLoad(); -private: - QFont font; - bool pixelSizeSet; - bool pointSizeSet; - mutable QQmlNullableValue<int> dpi; -}; - -class Q_QML_PRIVATE_EXPORT QQmlColorValueType : public QQmlValueType -{ - Q_PROPERTY(qreal r READ r WRITE setR) - Q_PROPERTY(qreal g READ g WRITE setG) - Q_PROPERTY(qreal b READ b WRITE setB) - Q_PROPERTY(qreal a READ a WRITE setA) - Q_OBJECT -public: - QQmlColorValueType(QObject *parent = 0); - - virtual void read(QObject *, int); - virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags); - virtual QVariant value(); - virtual void setValue(const QVariant &value); - virtual QString toString() const; - virtual bool isEqual(const QVariant &value) const; - - qreal r() const; - qreal g() const; - qreal b() const; - qreal a() const; - void setR(qreal); - void setG(qreal); - void setB(qreal); - void setA(qreal); - -private: - QColor color; -}; + 0, + 0 + }; -void QQmlValueType::onLoad() -{ + return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 9115e479e1..985d291a8e 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -68,7 +68,6 @@ #include "qqmlvaluetypeproxybinding_p.h" #include <QStack> -#include <QColor> #include <QPointF> #include <QSizeF> #include <QRectF> @@ -273,6 +272,17 @@ static QVariant variantFromString(const QString &string) QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.propertyIndex, a); \ QML_END_INSTR(name) +#define QML_STORE_PROVIDER_VALUE(name, type, value) \ + QML_BEGIN_INSTR(name) \ + struct { void *data[4]; } buffer; \ + if (QQml_valueTypeProvider()->storeValueType(type, &value, &buffer, sizeof(buffer))) { \ + void *a[] = { reinterpret_cast<void *>(&buffer), 0, &status, &flags }; \ + QObject *target = objects.top(); \ + CLEAN_PROPERTY(target, instr.propertyIndex); \ + QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.propertyIndex, a); \ + } \ + QML_END_INSTR(name) + #define QML_STORE_LIST(name, cpptype, value) \ QML_BEGIN_INSTR(name) \ cpptype v; \ @@ -372,7 +382,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_STORE_VALUE(StoreDouble, double, instr.value); QML_STORE_VALUE(StoreBool, bool, instr.value); QML_STORE_VALUE(StoreInteger, int, instr.value); - QML_STORE_VALUE(StoreColor, QColor, QColor::fromRgba(instr.value)); + QML_STORE_PROVIDER_VALUE(StoreColor, QMetaType::QColor, instr.value); QML_STORE_VALUE(StoreDate, QDate, QDate::fromJulianDay(instr.value)); QML_STORE_VALUE(StoreDateTime, QDateTime, QDateTime(QDate::fromJulianDay(instr.date), *(QTime *)&instr.time)); @@ -383,8 +393,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_STORE_POINTER(StoreSizeF, (QSizeF *)&instr.size); QML_STORE_POINTER(StoreRect, (QRect *)&instr.rect); QML_STORE_POINTER(StoreRectF, (QRectF *)&instr.rect); - QML_STORE_POINTER(StoreVector3D, (QVector3D *)&instr.vector); - QML_STORE_POINTER(StoreVector4D, (QVector4D *)&instr.vector); + QML_STORE_PROVIDER_VALUE(StoreVector3D, QMetaType::QVector3D, instr.vector); + QML_STORE_PROVIDER_VALUE(StoreVector4D, QMetaType::QVector4D, instr.vector); QML_STORE_POINTER(StoreString, &PRIMITIVES.at(instr.value)); QML_STORE_POINTER(StoreByteArray, &DATAS.at(instr.value)); QML_STORE_POINTER(StoreUrl, &URLS.at(instr.value)); @@ -696,11 +706,14 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, if (prop.type() & QQmlProperty::SignalProperty) { QMetaMethod method = QQmlMetaType::defaultMethod(assign); - if (method.signature() == 0) + if (!method.isValid()) VME_EXCEPTION(tr("Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())), instr.line); - if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature())) - VME_EXCEPTION(tr("Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())), instr.line); + if (!QMetaObject::checkConnectArgs(prop.method(), method)) { + VME_EXCEPTION(tr("Cannot connect mismatched signal/slot %1 %vs. %2") + .arg(QString::fromLatin1(method.methodSignature().constData())) + .arg(QString::fromLatin1(prop.method().methodSignature().constData())), instr.line); + } QQmlPropertyPrivate::connect(target, prop.index(), assign, method.methodIndex()); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index cc4ba091ce..afcc57e479 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -51,6 +51,7 @@ #include "qqmlpropertyvalueinterceptor_p.h" #include <private/qv8variantresource_p.h> +#include <private/qqmlglobal_p.h> Q_DECLARE_METATYPE(QJSValue); @@ -87,6 +88,7 @@ public: inline const void *dataPtr() const; inline void *dataPtr(); inline int dataType() const; + inline size_t dataSize() const; inline QObject *asQObject(); inline const QVariant &asQVariant(); @@ -95,7 +97,6 @@ public: inline double asDouble(); inline const QString &asQString(); inline const QUrl &asQUrl(); - inline const QColor &asQColor(); inline const QTime &asQTime(); inline const QDate &asQDate(); inline const QDateTime &asQDateTime(); @@ -108,11 +109,13 @@ public: inline void setValue(double); inline void setValue(const QString &); inline void setValue(const QUrl &); - inline void setValue(const QColor &); inline void setValue(const QTime &); inline void setValue(const QDate &); inline void setValue(const QDateTime &); inline void setValue(const QJSValue &); + + inline void setDataType(int t); + private: int type; void *data[6]; // Large enough to hold all types @@ -157,9 +160,6 @@ void QQmlVMEVariant::cleanup() } else if (type == QMetaType::QUrl) { ((QUrl *)dataPtr())->~QUrl(); type = QVariant::Invalid; - } else if (type == QMetaType::QColor) { - ((QColor *)dataPtr())->~QColor(); - type = QVariant::Invalid; } else if (type == QMetaType::QTime) { ((QTime *)dataPtr())->~QTime(); type = QVariant::Invalid; @@ -175,8 +175,11 @@ void QQmlVMEVariant::cleanup() } else if (type == qMetaTypeId<QJSValue>()) { ((QJSValue *)dataPtr())->~QJSValue(); type = QVariant::Invalid; + } else { + if (QQml_valueTypeProvider()->destroyValueType(type, dataPtr(), dataSize())) { + type = QVariant::Invalid; + } } - } int QQmlVMEVariant::dataType() const @@ -194,6 +197,11 @@ void *QQmlVMEVariant::dataPtr() return &data; } +size_t QQmlVMEVariant::dataSize() const +{ + return sizeof(data); +} + QObject *QQmlVMEVariant::asQObject() { if (type != QMetaType::QObjectStar) @@ -250,14 +258,6 @@ const QUrl &QQmlVMEVariant::asQUrl() return *(QUrl *)(dataPtr()); } -const QColor &QQmlVMEVariant::asQColor() -{ - if (type != QMetaType::QColor) - setValue(QColor()); - - return *(QColor *)(dataPtr()); -} - const QTime &QQmlVMEVariant::asQTime() { if (type != QMetaType::QTime) @@ -360,17 +360,6 @@ void QQmlVMEVariant::setValue(const QUrl &v) } } -void QQmlVMEVariant::setValue(const QColor &v) -{ - if (type != QMetaType::QColor) { - cleanup(); - type = QMetaType::QColor; - new (dataPtr()) QColor(v); - } else { - *(QColor *)(dataPtr()) = v; - } -} - void QQmlVMEVariant::setValue(const QTime &v) { if (type != QMetaType::QTime) { @@ -415,6 +404,11 @@ void QQmlVMEVariant::setValue(const QJSValue &v) } } +void QQmlVMEVariant::setDataType(int t) +{ + type = t; +} + QQmlVMEMetaObjectEndpoint::QQmlVMEMetaObjectEndpoint() { callback = &vmecallback; @@ -587,9 +581,6 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) case QVariant::Url: *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl(); break; - case QVariant::Color: - *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor(); - break; case QVariant::Date: *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate(); break; @@ -603,6 +594,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id); break; default: + QQml_valueTypeProvider()->readValueType(data[id].dataType(), data[id].dataPtr(), t, a[0]); break; } if (t == qMetaTypeId<QQmlListProperty<QObject> >()) { @@ -637,10 +629,6 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl(); data[id].setValue(*reinterpret_cast<QUrl *>(a[0])); break; - case QVariant::Color: - needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor(); - data[id].setValue(*reinterpret_cast<QColor *>(a[0])); - break; case QVariant::Date: needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate(); data[id].setValue(*reinterpret_cast<QDate *>(a[0])); @@ -657,6 +645,10 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) writeProperty(id, *reinterpret_cast<QVariant *>(a[0])); break; default: + needActivate = QQml_valueTypeProvider()->writeValueType(t, a[0], data[id].dataPtr(), data[id].dataSize()); + if (needActivate) { + data[id].setDataType(t); + } break; } } @@ -760,7 +752,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) // performance reasons; see QTBUG-24064) and thus compilation will have failed. QQmlError e; e.setDescription(QString(QLatin1String("Exception occurred during compilation of function: %1")). - arg(QLatin1String(QMetaObject::method(_id).signature()))); + arg(QLatin1String(QMetaObject::method(_id).methodSignature().constData()))); ep->warning(e); return -1; // The dynamic method with that id is not available. } diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index 1b5ceb8203..5bd472a067 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -58,7 +58,6 @@ #include <QtCore/QMetaObject> #include <QtCore/QBitArray> #include <QtCore/QPair> -#include <QtGui/QColor> #include <QtCore/QDate> #include <QtCore/qlist.h> #include <QtCore/qdebug.h> diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index f575f06d84..56743eb915 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -60,8 +60,6 @@ #include <QtCore/qstack.h> #include <QtCore/qdebug.h> -#include <QtCore/QStringBuilder> - #ifndef QT_NO_XMLSTREAMREADER #define V8THROW_REFERENCE(string) { \ diff --git a/src/qml/qml/qquicklistmodelworkeragent_p.h b/src/qml/qml/qquicklistmodelworkeragent_p.h index cf2ef45c16..24198b020c 100644 --- a/src/qml/qml/qquicklistmodelworkeragent_p.h +++ b/src/qml/qml/qquicklistmodelworkeragent_p.h @@ -55,7 +55,6 @@ #include <qqml.h> -#include <QtGui/qevent.h> #include <QMutex> #include <QWaitCondition> diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index db015b07d6..e055cad4f2 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -46,6 +46,7 @@ #include "qv4compiler_p.h" #include "qv4compiler_p_p.h" +#include <private/qqmlglobal_p.h> #include <private/qqmlaccessors_p.h> #include <private/qqmlprofilerservice_p.h> #include <private/qqmlmetatype_p.h> @@ -93,12 +94,11 @@ struct Register { inline QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); } inline QString *getstringptr() { return (QString *)typeDataPtr(); } inline QUrl *geturlptr() { return (QUrl *)typeDataPtr(); } - inline QColor *getcolorptr() { return (QColor *)typeDataPtr(); } inline const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); } inline const QString *getstringptr() const { return (QString *)typeDataPtr(); } inline const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); } - inline const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); } + size_t dataSize() { return sizeof(data); } inline void *typeDataPtr() { return (void *)&data; } inline void *typeMemory() { return (void *)data; } inline const void *typeDataPtr() const { return (void *)&data; } @@ -147,7 +147,7 @@ void Register::cleanup() } else if (dataType == QUrlType) { geturlptr()->~QUrl(); } else if (dataType == QColorType) { - getcolorptr()->~QColor(); + QQml_valueTypeProvider()->destroyValueType(QMetaType::QColor, typeDataPtr(), dataSize()); } else if (dataType == QVariantType) { getvariantptr()->~QVariant(); } @@ -169,7 +169,7 @@ void Register::cleanupUrl() void Register::cleanupColor() { - getcolorptr()->~QColor(); + QQml_valueTypeProvider()->destroyValueType(QMetaType::QColor, typeDataPtr(), dataSize()); setUndefined(); } @@ -188,7 +188,7 @@ void Register::copy(const Register &other) else if (other.dataType == QUrlType) new (geturlptr()) QUrl(*other.geturlptr()); else if (other.dataType == QColorType) - new (getcolorptr()) QColor(*other.getcolorptr()); + QQml_valueTypeProvider()->copyValueType(QMetaType::QColor, other.typeDataPtr(), typeDataPtr(), dataSize()); else if (other.dataType == QVariantType) new (getvariantptr()) QVariant(*other.getvariantptr()); } @@ -203,7 +203,7 @@ void Register::init(Type type) else if (dataType == QUrlType) new (geturlptr()) QUrl(); else if (dataType == QColorType) - new (getcolorptr()) QColor(); + QQml_valueTypeProvider()->initValueType(QMetaType::QColor, typeDataPtr(), dataSize()); else if (dataType == QVariantType) new (getvariantptr()) QVariant(); } @@ -507,7 +507,7 @@ static void testBindingResult(const QString &binding, int line, int column, v4value = result.getnumber(); break; case QMetaType::QColor: - v4value = *result.getcolorptr(); + v4value = QVariant(QMetaType::QColor, result.typeDataPtr()); break; case QMetaType::QVariant: v4value = *result.getvariantptr(); @@ -1085,8 +1085,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, output.cleanupString(); MARK_CLEAN_REGISTER(instr->unaryop.output); } - QColor *colorPtr = output.getcolorptr(); - new (colorPtr) QColor(QQmlStringConverters::colorFromString(tmp)); + QQml_valueTypeProvider()->createValueFromString(QMetaType::QColor, tmp, output.typeDataPtr(), output.dataSize()); COLOR_REGISTER(instr->unaryop.output); } @@ -1190,13 +1189,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, if (src.isUndefined()) { output.setUndefined(); } else { - const QColor tmp(*src.getcolorptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupColor(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - // to maintain behaviour with QtQuick 1.0, we just output normal toString() value. - new (output.getstringptr()) QString(QVariant(tmp).toString()); + QQml_valueTypeProvider()->createStringFromValue(QMetaType::QColor, src.typeDataPtr(), output.getstringptr()); STRING_REGISTER(instr->unaryop.output); } } @@ -1210,7 +1203,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, if (src.isUndefined()) { output.setUndefined(); } else { - const QColor tmp(*src.getcolorptr()); + QVariant tmp(QMetaType::QColor, src.typeDataPtr()); if (instr->unaryop.src == instr->unaryop.output) { output.cleanupColor(); MARK_CLEAN_REGISTER(instr->unaryop.output); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index c8f178db08..9c570d756b 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -51,6 +51,7 @@ #include <private/qv8profilerservice_p.h> #include <private/qqmlprofilerservice_p.h> +#include <private/qqmlglobal_p.h> #include <QtCore/qstring.h> #include <QtCore/qdatetime.h> @@ -62,12 +63,6 @@ #include <QtCore/qfile.h> #include <QtCore/qcoreapplication.h> -#include <QtGui/qcolor.h> -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> -#include <QtGui/qdesktopservices.h> -#include <QtGui/qfontdatabase.h> - QT_BEGIN_NAMESPACE namespace QQmlBuiltinFunctions { @@ -417,7 +412,7 @@ v8::Handle<v8::Value> rgba(const v8::Arguments &args) if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - return V8ENGINE()->fromVariant(QVariant::fromValue(QColor::fromRgbF(r, g, b, a))); + return V8ENGINE()->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)); } /*! @@ -446,7 +441,7 @@ v8::Handle<v8::Value> hsla(const v8::Arguments &args) if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - return V8ENGINE()->fromVariant(QVariant::fromValue(QColor::fromHslF(h, s, l, a))); + return V8ENGINE()->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)); } /*! @@ -508,11 +503,13 @@ v8::Handle<v8::Value> vector3d(const v8::Arguments &args) if (args.Length() != 3) V8THROW_ERROR("Qt.vector(): Invalid arguments"); - double x = args[0]->ToNumber()->Value(); - double y = args[1]->ToNumber()->Value(); - double z = args[2]->ToNumber()->Value(); + float xyz[3]; + xyz[0] = args[0]->ToNumber()->Value(); + xyz[1] = args[1]->ToNumber()->Value(); + xyz[2] = args[2]->ToNumber()->Value(); - return V8ENGINE()->fromVariant(QVariant::fromValue(QVector3D(x, y, z))); + const void *params[] = { xyz }; + return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)); } /*! @@ -524,12 +521,14 @@ v8::Handle<v8::Value> vector4d(const v8::Arguments &args) if (args.Length() != 4) V8THROW_ERROR("Qt.vector4d(): Invalid arguments"); - double x = args[0]->NumberValue(); - double y = args[1]->NumberValue(); - double z = args[2]->NumberValue(); - double w = args[3]->NumberValue(); + float xyzw[4]; + xyzw[0] = args[0]->ToNumber()->Value(); + xyzw[1] = args[1]->ToNumber()->Value(); + xyzw[2] = args[2]->ToNumber()->Value(); + xyzw[3] = args[3]->ToNumber()->Value(); - return V8ENGINE()->fromVariant(QVariant::fromValue(QVector4D(x, y, z, w))); + const void *params[] = { xyzw }; + return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)); } /*! @@ -551,17 +550,14 @@ v8::Handle<v8::Value> lighter(const v8::Arguments &args) if (args.Length() != 1 && args.Length() != 2) V8THROW_ERROR("Qt.lighter(): Invalid arguments"); - QColor color; QVariant v = V8ENGINE()->toVariant(args[0], -1); - if (v.userType() == QVariant::Color) { - color = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { + if (v.userType() == QVariant::String) { bool ok = false; - color = QQmlStringConverters::colorFromString(v.toString(), &ok); + v = QQmlStringConverters::colorFromString(v.toString(), &ok); if (!ok) { return v8::Null(); } - } else { + } else if (v.userType() != QVariant::Color) { return v8::Null(); } @@ -569,8 +565,7 @@ v8::Handle<v8::Value> lighter(const v8::Arguments &args) if (args.Length() == 2) factor = args[1]->ToNumber()->Value(); - color = color.lighter(int(qRound(factor*100.))); - return V8ENGINE()->fromVariant(QVariant::fromValue(color)); + return V8ENGINE()->fromVariant(QQml_colorProvider()->lighter(v, factor)); } /*! @@ -593,17 +588,14 @@ v8::Handle<v8::Value> darker(const v8::Arguments &args) if (args.Length() != 1 && args.Length() != 2) V8THROW_ERROR("Qt.darker(): Invalid arguments"); - QColor color; QVariant v = V8ENGINE()->toVariant(args[0], -1); - if (v.userType() == QVariant::Color) { - color = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { + if (v.userType() == QVariant::String) { bool ok = false; - color = QQmlStringConverters::colorFromString(v.toString(), &ok); + v = QQmlStringConverters::colorFromString(v.toString(), &ok); if (!ok) { return v8::Null(); } - } else { + } else if (v.userType() != QVariant::Color) { return v8::Null(); } @@ -611,8 +603,7 @@ v8::Handle<v8::Value> darker(const v8::Arguments &args) if (args.Length() == 2) factor = args[1]->ToNumber()->Value(); - color = color.darker(int(qRound(factor*100.))); - return V8ENGINE()->fromVariant(QVariant::fromValue(color)); + return V8ENGINE()->fromVariant(QQml_colorProvider()->darker(v, factor)); } /*! @@ -645,53 +636,30 @@ v8::Handle<v8::Value> tint(const v8::Arguments &args) V8THROW_ERROR("Qt.tint(): Invalid arguments"); // base color - QColor color; - QVariant v = V8ENGINE()->toVariant(args[0], -1); - if (v.userType() == QVariant::Color) { - color = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { + QVariant v1 = V8ENGINE()->toVariant(args[0], -1); + if (v1.userType() == QVariant::String) { bool ok = false; - color = QQmlStringConverters::colorFromString(v.toString(), &ok); + v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok); if (!ok) { return v8::Null(); } - } else { + } else if (v1.userType() != QVariant::Color) { return v8::Null(); } // tint color - QColor tintColor; - v = V8ENGINE()->toVariant(args[1], -1); - if (v.userType() == QVariant::Color) { - tintColor = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { + QVariant v2 = V8ENGINE()->toVariant(args[1], -1); + if (v2.userType() == QVariant::String) { bool ok = false; - tintColor = QQmlStringConverters::colorFromString(v.toString(), &ok); + v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok); if (!ok) { return v8::Null(); } - } else { + } else if (v2.userType() != QVariant::Color) { return v8::Null(); } - // tint the base color and return the final color - QColor finalColor; - int a = tintColor.alpha(); - if (a == 0xFF) - finalColor = tintColor; - else if (a == 0x00) - finalColor = color; - else { - qreal a = tintColor.alphaF(); - qreal inv_a = 1.0 - a; - - finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a, - tintColor.greenF() * a + color.greenF() * inv_a, - tintColor.blueF() * a + color.blueF() * inv_a, - a + inv_a * color.alphaF()); - } - - return V8ENGINE()->fromVariant(QVariant::fromValue(finalColor)); + return V8ENGINE()->fromVariant(QQml_colorProvider()->tint(v1, v2)); } /*! @@ -908,11 +876,8 @@ v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args) if (args.Length() != 1) return V8ENGINE()->fromVariant(false); - bool ret = false; -#ifndef QT_NO_DESKTOPSERVICES - ret = QDesktopServices::openUrl(V8ENGINE()->toVariant(resolvedUrl(args), -1).toUrl()); -#endif - return V8ENGINE()->fromVariant(ret); + QUrl url(V8ENGINE()->toVariant(resolvedUrl(args), -1).toUrl()); + return V8ENGINE()->fromVariant(QQml_guiProvider()->openUrlExternally(url)); } /*! @@ -945,8 +910,7 @@ v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args) if (args.Length() != 0) V8THROW_ERROR("Qt.fontFamilies(): Invalid arguments"); - QFontDatabase database; - return V8ENGINE()->fromVariant(database.families()); + return V8ENGINE()->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())); } /*! @@ -1364,6 +1328,65 @@ v8::Handle<v8::Value> locale(const v8::Arguments &args) return QQmlLocale::locale(v8engine, code); } +/*! + \qmlmethod Qt::binding(function) + + Returns a JS object representing a binding expression which may be + assigned to any property in imperative code to cause a binding + assignment. + + There are two main use-cases for the function: firstly, in imperative + JavaScript code to cause a binding assignment: + + \snippet doc/src/snippets/declarative/qtBinding.1.qml 0 + + and secondly, when defining initial property values of dynamically + constructed objects (via Component.createObject() or + Loader.setSource()) as being bound to the result of an expression. + + For example, assuming the existence of a DynamicText component: + \snippet doc/src/snippets/declarative/DynamicText.qml 0 + + the output from: + \snippet doc/src/snippets/declarative/qtBinding.2.qml 0 + + and from: + \snippet doc/src/snippets/declarative/qtBinding.3.qml 0 + + should both be: + \code + Root text extra text + Modified root text extra text + Dynamic text extra text + Modified dynamic text extra text + \endcode + + This function cannot be used in property binding declarations + (see the documentation on \l{qml-javascript-assignment}{binding + declarations and binding assignments}) except when the result is + stored in an array bound to a var property. + + \snippet doc/src/snippets/declarative/qtBinding.4.qml 0 + + Note: in QtQuick 1.x, all function assignment was treated as + binding assignment, so the Qt.binding() function is new in + QtQuick 2.0. + + \since QtQuick 2.0 +*/ +v8::Handle<v8::Value> binding(const v8::Arguments &args) +{ + QString code; + if (args.Length() != 1) + V8THROW_ERROR("binding() requires 1 argument"); + if (!args[0]->IsFunction()) + V8THROW_TYPE("binding(): argument (binding expression) must be a function"); + + v8::Handle<v8::Object> rv = args[0]->ToObject()->Clone(); + rv->SetHiddenValue(V8ENGINE()->bindingFlagKey(), v8::Boolean::New(true)); + return rv; +} + } // namespace QQmlBuiltinFunctions QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index ddb1c64243..bbfe88a292 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -103,6 +103,7 @@ v8::Handle<v8::Value> qsTrId(const v8::Arguments &args); v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args); v8::Handle<v8::Value> stringArg(const v8::Arguments &args); v8::Handle<v8::Value> locale(const v8::Arguments &args); +v8::Handle<v8::Value> binding(const v8::Arguments &args); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8bindings.cpp b/src/qml/qml/v8/qv8bindings.cpp index 025854f1ac..65c395e013 100644 --- a/src/qml/qml/v8/qv8bindings.cpp +++ b/src/qml/qml/v8/qv8bindings.cpp @@ -144,10 +144,7 @@ void QV8Bindings::Binding::update(QQmlPropertyPrivate::WriteFlags flags) if (!watcher.wasDeleted() && !destroyedFlag()) { if (needsErrorData) { - QUrl url = parent->url(); - if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); - - delayedError()->error.setUrl(url); + delayedError()->error.setUrl(parent->url()); delayedError()->error.setLine(instruction->line); delayedError()->error.setColumn(-1); } diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 6b034c0ff6..8444d657ec 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -41,8 +41,6 @@ #include "qv8engine_p.h" -#include <QtGui/QGuiApplication> - #include "qv8contextwrapper_p.h" #include "qv8valuetypewrapper_p.h" #include "qv8sequencewrapper_p.h" @@ -52,14 +50,17 @@ #include <private/qqmlbuiltinfunctions_p.h> #include <private/qqmllist_p.h> #include <private/qqmlengine_p.h> -#include <private/qquickapplication_p.h> #include <private/qqmlxmlhttprequest_p.h> #include <private/qqmllocale_p.h> +#include <private/qqmlglobal_p.h> #include "qscript_impl_p.h" #include "qv8domerrors_p.h" #include "qv8sqlerrors_p.h" +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qjsonvalue.h> Q_DECLARE_METATYPE(QJSValue) Q_DECLARE_METATYPE(QList<int>) @@ -124,6 +125,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership) , m_ownsV8Context(ownership == QJSEngine::CreateNewContext) , m_xmlHttpRequestData(0) , m_listModelData(0) + , m_application(0) { qMetaTypeId<QJSValue>(); qMetaTypeId<QList<int> >(); @@ -146,6 +148,8 @@ QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership) QV8GCCallback::registerGcPrologueCallback(); m_strongReferencer = qPersistentNew(v8::Object::New()); + m_bindingFlagKey = qPersistentNew(v8::String::New("qml::binding")); + m_stringWrapper.init(); m_contextWrapper.init(this); m_qobjectWrapper.init(this); @@ -154,6 +158,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership) m_variantWrapper.init(this); m_valueTypeWrapper.init(this); m_sequenceWrapper.init(this); + m_jsonWrapper.init(this); { v8::Handle<v8::Value> v = global()->Get(v8::String::New("Object"))->ToObject()->Get(v8::String::New("getOwnPropertyNames")); @@ -181,6 +186,7 @@ QV8Engine::~QV8Engine() qPersistentDispose(m_strongReferencer); + m_jsonWrapper.destroy(); m_sequenceWrapper.destroy(); m_valueTypeWrapper.destroy(); m_variantWrapper.destroy(); @@ -190,6 +196,8 @@ QV8Engine::~QV8Engine() m_contextWrapper.destroy(); m_stringWrapper.destroy(); + qPersistentDispose(m_bindingFlagKey); + m_originalGlobalObject.destroy(); if (m_ownsV8Context) @@ -217,6 +225,9 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) if (typeHint == QVariant::Bool) return QVariant(value->BooleanValue()); + if (typeHint == QMetaType::QJsonValue) + return QVariant::fromValue(jsonValueFromJS(value)); + if (value->IsObject()) { QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource(); if (r) { @@ -248,6 +259,9 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) case QV8ObjectResource::SequenceType: return m_sequenceWrapper.toVariant(r); } + } else if (typeHint == QMetaType::QJsonObject + && !value->IsArray() && !value->IsFunction()) { + return QVariant::fromValue(jsonObjectFromJS(value)); } } @@ -266,6 +280,8 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) } return qVariantFromValue<QList<QObject*> >(list); + } else if (typeHint == QMetaType::QJsonArray) { + return QVariant::fromValue(jsonArrayFromJS(value)); } bool succeeded = false; @@ -313,6 +329,7 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant) if (type < QMetaType::User) { switch (QMetaType::Type(type)) { + case QMetaType::UnknownType: case QMetaType::Void: return v8::Undefined(); case QMetaType::Bool: @@ -364,6 +381,12 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant) return arrayFromVariantList(this, *reinterpret_cast<const QVariantList *>(ptr)); case QMetaType::QVariantMap: return objectFromVariantMap(this, *reinterpret_cast<const QVariantMap *>(ptr)); + case QMetaType::QJsonValue: + return jsonValueToJS(*reinterpret_cast<const QJsonValue *>(ptr)); + case QMetaType::QJsonObject: + return jsonObjectToJS(*reinterpret_cast<const QJsonObject *>(ptr)); + case QMetaType::QJsonArray: + return jsonArrayToJS(*reinterpret_cast<const QJsonArray *>(ptr)); default: break; @@ -532,9 +555,6 @@ QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value) -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> - struct StaticQtMetaObject : public QObject { static const QMetaObject *get() @@ -597,10 +617,11 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global) qt->Set(v8::String::New("atob"), V8FUNCTION(atob, this)); qt->Set(v8::String::New("resolvedUrl"), V8FUNCTION(resolvedUrl, this)); qt->Set(v8::String::New("locale"), V8FUNCTION(locale, this)); + qt->Set(v8::String::New("binding"), V8FUNCTION(binding, this)); if (m_engine) { - qt->Set(v8::String::New("application"), newQObject(new QQuickApplication(m_engine))); - qt->Set(v8::String::New("inputMethod"), newQObject(qGuiApp->inputMethod(), CppOwnership)); + qt->SetAccessor(v8::String::New("application"), getApplication, 0, v8::External::New(this)); + qt->SetAccessor(v8::String::New("inputMethod"), getInputMethod, 0, v8::External::New(this)); qt->Set(v8::String::New("lighter"), V8FUNCTION(lighter, this)); qt->Set(v8::String::New("darker"), V8FUNCTION(darker, this)); qt->Set(v8::String::New("tint"), V8FUNCTION(tint, this)); @@ -1089,6 +1110,7 @@ v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data) // check if it's one of the types we know switch (QMetaType::Type(type)) { + case QMetaType::UnknownType: case QMetaType::Void: return v8::Undefined(); case QMetaType::Bool: @@ -1149,6 +1171,15 @@ v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data) case QMetaType::QVariant: result = variantToJS(*reinterpret_cast<const QVariant*>(data)); break; + case QMetaType::QJsonValue: + result = jsonValueToJS(*reinterpret_cast<const QJsonValue *>(data)); + break; + case QMetaType::QJsonObject: + result = jsonObjectToJS(*reinterpret_cast<const QJsonObject *>(data)); + break; + case QMetaType::QJsonArray: + result = jsonArrayToJS(*reinterpret_cast<const QJsonArray *>(data)); + break; default: if (type == qMetaTypeId<QJSValue>()) { return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->asV8Value(this); @@ -1264,6 +1295,15 @@ bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data case QMetaType::QVariant: *reinterpret_cast<QVariant*>(data) = variantFromJS(value); return true; + case QMetaType::QJsonValue: + *reinterpret_cast<QJsonValue *>(data) = jsonValueFromJS(value); + return true; + case QMetaType::QJsonObject: + *reinterpret_cast<QJsonObject *>(data) = jsonObjectFromJS(value); + return true; + case QMetaType::QJsonArray: + *reinterpret_cast<QJsonArray *>(data) = jsonArrayFromJS(value); + return true; default: ; } @@ -1380,6 +1420,36 @@ QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value) return variantMapFromJS(value->ToObject()); } +v8::Handle<v8::Value> QV8Engine::jsonValueToJS(const QJsonValue &value) +{ + return m_jsonWrapper.fromJsonValue(value); +} + +QJsonValue QV8Engine::jsonValueFromJS(v8::Handle<v8::Value> value) +{ + return m_jsonWrapper.toJsonValue(value); +} + +v8::Local<v8::Object> QV8Engine::jsonObjectToJS(const QJsonObject &object) +{ + return m_jsonWrapper.fromJsonObject(object); +} + +QJsonObject QV8Engine::jsonObjectFromJS(v8::Handle<v8::Value> value) +{ + return m_jsonWrapper.toJsonObject(value); +} + +v8::Local<v8::Array> QV8Engine::jsonArrayToJS(const QJsonArray &array) +{ + return m_jsonWrapper.fromJsonArray(array); +} + +QJsonArray QV8Engine::jsonArrayFromJS(v8::Handle<v8::Value> value) +{ + return m_jsonWrapper.toJsonArray(value); +} + bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value, const QByteArray &targetType, void **result) @@ -1501,6 +1571,22 @@ int QV8Engine::consoleCountHelper(const QString &file, int line, int column) return number; } +v8::Handle<v8::Value> QV8Engine::getApplication(v8::Local<v8::String>, const v8::AccessorInfo &info) +{ + QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Unwrap(info.Data())); + if (!engine->m_application) { + // Only allocate an application object once + engine->m_application = QQml_guiProvider()->application(engine->m_engine); + } + return engine->newQObject(engine->m_application); +} + +v8::Handle<v8::Value> QV8Engine::getInputMethod(v8::Local<v8::String>, const v8::AccessorInfo &info) +{ + QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Unwrap(info.Data())); + return engine->newQObject(QQml_guiProvider()->inputMethod(), CppOwnership); +} + void QV8GCCallback::registerGcPrologueCallback() { QV8Engine::ThreadData *td = QV8Engine::threadData(); diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index bc57b27085..1fc03d82e5 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -80,6 +80,7 @@ #include "qv8variantwrapper_p.h" #include "qv8valuetypewrapper_p.h" #include "qv8sequencewrapper_p.h" +#include "qv8jsonwrapper_p.h" QT_BEGIN_NAMESPACE @@ -357,6 +358,9 @@ public: // a QVariant wrapper inline v8::Handle<v8::Value> newQVariant(const QVariant &); + // Return the JS string key for the "function is a binding" flag + inline v8::Handle<v8::String> bindingFlagKey() const; + // Return the network access manager for this engine. By default this returns the network // access manager of the QQmlEngine. It is overridden in the case of a threaded v8 // instance (like in WorkerScript). @@ -412,6 +416,13 @@ public: v8::Handle<v8::Value> variantToJS(const QVariant &value); QVariant variantFromJS(v8::Handle<v8::Value> value); + v8::Handle<v8::Value> jsonValueToJS(const QJsonValue &value); + QJsonValue jsonValueFromJS(v8::Handle<v8::Value> value); + v8::Local<v8::Object> jsonObjectToJS(const QJsonObject &object); + QJsonObject jsonObjectFromJS(v8::Handle<v8::Value> value); + v8::Local<v8::Array> jsonArrayToJS(const QJsonArray &array); + QJsonArray jsonArrayFromJS(v8::Handle<v8::Value> value); + v8::Handle<v8::Value> metaTypeToJS(int type, const void *data); bool metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data); @@ -440,6 +451,9 @@ public: void addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle); void addRelationshipForGC(QObject *object, QObject *other); + static v8::Handle<v8::Value> getApplication(v8::Local<v8::String> property, const v8::AccessorInfo &info); + static v8::Handle<v8::Value> getInputMethod(v8::Local<v8::String> property, const v8::AccessorInfo &info); + struct ThreadData { ThreadData(); ~ThreadData(); @@ -461,6 +475,8 @@ protected: v8::Persistent<v8::Context> m_context; QScriptOriginalGlobalObject m_originalGlobalObject; + v8::Persistent<v8::String> m_bindingFlagKey; + QV8StringWrapper m_stringWrapper; QV8ContextWrapper m_contextWrapper; QV8QObjectWrapper m_qobjectWrapper; @@ -469,6 +485,7 @@ protected: QV8VariantWrapper m_variantWrapper; QV8ValueTypeWrapper m_valueTypeWrapper; QV8SequenceWrapper m_sequenceWrapper; + QV8JsonWrapper m_jsonWrapper; v8::Persistent<v8::Function> m_getOwnPropertyNames; v8::Persistent<v8::Function> m_freezeObject; @@ -487,6 +504,8 @@ protected: QHash<QString, quint32> m_consoleCount; + QObject *m_application; + QVariant toBasicVariant(v8::Handle<v8::Value>); void initializeGlobal(v8::Handle<v8::Object>); @@ -609,6 +628,11 @@ v8::Handle<v8::Value> QV8Engine::newSequence(int sequenceType, QObject *object, return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded); } +v8::Handle<v8::String> QV8Engine::bindingFlagKey() const +{ + return m_bindingFlagKey; +} + // XXX Can this be made more optimal? It is called prior to resolving each and every // unqualified name in QV8ContextWrapper. bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string) diff --git a/src/qml/qml/v8/qv8jsonwrapper.cpp b/src/qml/qml/v8/qv8jsonwrapper.cpp new file mode 100644 index 0000000000..ff8cc4faba --- /dev/null +++ b/src/qml/qml/v8/qv8jsonwrapper.cpp @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv8jsonwrapper_p.h" +#include "qv8engine_p.h" +#include "qjsconverter_impl_p.h" + +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qjsonvalue.h> + +QT_BEGIN_NAMESPACE + +QV8JsonWrapper::QV8JsonWrapper() +: m_engine(0) +{ +} + +QV8JsonWrapper::~QV8JsonWrapper() +{ +} + +void QV8JsonWrapper::init(QV8Engine *engine) +{ + m_engine = engine; +} + +void QV8JsonWrapper::destroy() +{ +} + +v8::Handle<v8::Value> QV8JsonWrapper::fromJsonValue(const QJsonValue &value) +{ + if (value.isString()) + return QJSConverter::toString(value.toString()); + else if (value.isDouble()) + return v8::Number::New(value.toDouble()); + else if (value.isBool()) + return value.toBool() ? v8::True() : v8::False(); + else if (value.isArray()) + return fromJsonArray(value.toArray()); + else if (value.isObject()) + return fromJsonObject(value.toObject()); + else if (value.isNull()) + return v8::Null(); + else + return v8::Undefined(); +} + +QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value) +{ + if (value->IsString()) + return QJsonValue(QJSConverter::toString(value.As<v8::String>())); + else if (value->IsNumber()) + return QJsonValue(value->NumberValue()); + else if (value->IsBoolean()) + return QJsonValue(value->BooleanValue()); + else if (value->IsArray()) + return toJsonArray(value.As<v8::Array>()); + else if (value->IsObject()) + return toJsonObject(value.As<v8::Object>()); + else if (value->IsNull()) + return QJsonValue(QJsonValue::Null); + else + return QJsonValue(QJsonValue::Undefined); +} + +v8::Local<v8::Object> QV8JsonWrapper::fromJsonObject(const QJsonObject &object) +{ + v8::Local<v8::Object> v8object = v8::Object::New(); + for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it) + v8object->Set(QJSConverter::toString(it.key()), fromJsonValue(it.value())); + return v8object; +} + +QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value) +{ + QJsonObject result; + if (!value->IsObject() || value->IsArray() || value->IsFunction()) + return result; + + v8::Handle<v8::Object> v8object(value.As<v8::Object>()); + int hash = v8object->GetIdentityHash(); + if (m_visitedConversionObjects.contains(hash)) { + // Avoid recursion. + // For compatibility with QVariant{List,Map} conversion, we return an + // empty object (and no error is thrown). + return result; + } + + m_visitedConversionObjects.insert(hash); + + v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object); + uint32_t length = propertyNames->Length(); + for (uint32_t i = 0; i < length; ++i) { + v8::Local<v8::Value> name = propertyNames->Get(i); + v8::Local<v8::Value> propertyValue = v8object->Get(name); + if (!propertyValue->IsFunction()) + result.insert(QJSConverter::toString(name->ToString()), toJsonValue(propertyValue)); + } + + m_visitedConversionObjects.remove(hash); + + return result; +} + +v8::Local<v8::Array> QV8JsonWrapper::fromJsonArray(const QJsonArray &array) +{ + int size = array.size(); + v8::Local<v8::Array> v8array = v8::Array::New(size); + for (int i = 0; i < size; i++) + v8array->Set(i, fromJsonValue(array.at(i))); + return v8array; +} + +QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value) +{ + QJsonArray result; + if (!value->IsArray()) + return result; + + v8::Handle<v8::Array> v8array(value.As<v8::Array>()); + int hash = v8array->GetIdentityHash(); + if (m_visitedConversionObjects.contains(hash)) { + // Avoid recursion. + // For compatibility with QVariant{List,Map} conversion, we return an + // empty array (and no error is thrown). + return result; + } + + m_visitedConversionObjects.insert(hash); + + uint32_t length = v8array->Length(); + for (uint32_t i = 0; i < length; ++i) { + v8::Local<v8::Value> element = v8array->Get(i); + if (!element->IsFunction()) + result.append(toJsonValue(element)); + } + + m_visitedConversionObjects.remove(hash); + + return result; +} + +QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8jsonwrapper_p.h b/src/qml/qml/v8/qv8jsonwrapper_p.h new file mode 100644 index 0000000000..842a3aa5d5 --- /dev/null +++ b/src/qml/qml/v8/qv8jsonwrapper_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QV8JSONWRAPPER_P_H +#define QV8JSONWRAPPER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtCore/qset.h> +#include <private/qv8_p.h> + +QT_BEGIN_NAMESPACE + +class QJsonValue; +class QJsonObject; +class QJsonArray; + +class QV8Engine; +class QV8JsonWrapper +{ +public: + QV8JsonWrapper(); + ~QV8JsonWrapper(); + + void init(QV8Engine *); + void destroy(); + + v8::Handle<v8::Value> fromJsonValue(const QJsonValue &value); + QJsonValue toJsonValue(v8::Handle<v8::Value> value); + + v8::Local<v8::Object> fromJsonObject(const QJsonObject &object); + QJsonObject toJsonObject(v8::Handle<v8::Value> value); + + v8::Local<v8::Array> fromJsonArray(const QJsonArray &array); + QJsonArray toJsonArray(v8::Handle<v8::Value> value); + +private: + QV8Engine *m_engine; + QSet<int> m_visitedConversionObjects; +}; + +QT_END_NAMESPACE + +#endif // QV8JSONWRAPPER_P_H + diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 480c9f9d6f..176d4fb76f 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -54,6 +54,7 @@ #include <private/qqmlexpression_p.h> #include <QtQml/qjsvalue.h> +#include <QtCore/qjsonvalue.h> #include <QtCore/qvarlengtharray.h> #include <QtCore/qtimer.h> #include <QtCore/qatomic.h> @@ -449,7 +450,7 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, return retn; } - if (property.propType == QVariant::Invalid) { + if (property.propType == QMetaType::UnknownType) { QMetaProperty p = object->metaObject()->property(property.coreIndex); qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property " "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name()); @@ -524,7 +525,7 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject return v8::Handle<v8::Value>(); } - if (result->isFunction()) { + if (result->isFunction() && !result->isVMEProperty()) { if (result->isVMEFunction()) { return ((QQmlVMEMetaObject *)(object->metaObject()))->vmeMethod(result->coreIndex); } else if (result->isV8Function()) { @@ -584,23 +585,53 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert v8::Handle<v8::Value> value) { QQmlBinding *newBinding = 0; - if (value->IsFunction()) { - QQmlContextData *context = engine->callingContext(); - v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value); - - v8::Local<v8::StackTrace> trace = - v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | - v8::StackTrace::kScriptName)); - v8::Local<v8::StackFrame> frame = trace->GetFrame(0); - int lineNumber = frame->GetLineNumber(); - int columnNumber = frame->GetColumn(); - QString url = engine->toString(frame->GetScriptName()); - - newBinding = new QQmlBinding(&function, object, context, url, lineNumber, columnNumber); - newBinding->setTarget(object, *property, context); - newBinding->setEvaluateFlags(newBinding->evaluateFlags() | - QQmlBinding::RequiresThisObject); + if (value->ToObject()->GetHiddenValue(engine->bindingFlagKey()).IsEmpty()) { + if (!property->isVMEProperty()) { + // XXX TODO: uncomment the following lines + // assigning a JS function to a non-var-property is not allowed. + //QString error = QLatin1String("Cannot assign JavaScript function to ") + + // QLatin1String(QMetaType::typeName(property->propType)); + //v8::ThrowException(v8::Exception::Error(engine->toString(error))); + //return; + // XXX TODO: remove the following transition behaviour + // Temporarily allow assignment of functions to non-var properties + // to mean binding assignment (as per old behaviour). + QQmlContextData *context = engine->callingContext(); + v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value); + + v8::Local<v8::StackTrace> trace = + v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | + v8::StackTrace::kScriptName)); + v8::Local<v8::StackFrame> frame = trace->GetFrame(0); + int lineNumber = frame->GetLineNumber(); + int columnNumber = frame->GetColumn(); + QString url = engine->toString(frame->GetScriptName()); + + newBinding = new QQmlBinding(&function, object, context, url, lineNumber, columnNumber); + newBinding->setTarget(object, *property, context); + newBinding->setEvaluateFlags(newBinding->evaluateFlags() | + QQmlBinding::RequiresThisObject); + qWarning("WARNING: function assignment is DEPRECATED and will be removed! Wrap RHS in Qt.binding(): %s:%d", qPrintable(engine->toString(frame->GetScriptName())), frame->GetLineNumber()); + } + } else { + // binding assignment. + QQmlContextData *context = engine->callingContext(); + v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value); + + v8::Local<v8::StackTrace> trace = + v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | + v8::StackTrace::kScriptName)); + v8::Local<v8::StackFrame> frame = trace->GetFrame(0); + int lineNumber = frame->GetLineNumber(); + int columnNumber = frame->GetColumn(); + QString url = engine->toString(frame->GetScriptName()); + + newBinding = new QQmlBinding(&function, object, context, url, lineNumber, columnNumber); + newBinding->setTarget(object, *property, context); + newBinding->setEvaluateFlags(newBinding->evaluateFlags() | + QQmlBinding::RequiresThisObject); + } } QQmlAbstractBinding *oldBinding = @@ -608,6 +639,12 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert if (oldBinding) oldBinding->destroy(); + if (!newBinding && property->isVMEProperty()) { + // allow assignment of "special" values (null, undefined, function) to var properties + static_cast<QQmlVMEMetaObject *>(const_cast<QMetaObject *>(object->metaObject()))->setVMEProperty(property->coreIndex, value); + return; + } + #define PROPERTY_STORE(cpptype, value) \ cpptype o = value; \ int status = -1; \ @@ -623,6 +660,8 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert QMetaObject::metacall(object, QMetaObject::ResetProperty, property->coreIndex, a); } else if (value->IsUndefined() && property->propType == qMetaTypeId<QVariant>()) { PROPERTY_STORE(QVariant, QVariant()); + } else if (value->IsUndefined() && property->propType == QMetaType::QJsonValue) { + PROPERTY_STORE(QJsonValue, QJsonValue(QJsonValue::Undefined)); } else if (value->IsUndefined()) { QString error = QLatin1String("Cannot assign [undefined] to ") + QLatin1String(QMetaType::typeName(property->propType)); @@ -654,10 +693,14 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert if (v.userType() == QVariant::Invalid) valueType = "null"; else valueType = QMetaType::typeName(v.userType()); + const char *targetTypeName = QMetaType::typeName(property->propType); + if (!targetTypeName) + targetTypeName = "an unregistered type"; + QString error = QLatin1String("Cannot assign ") + QLatin1String(valueType) + QLatin1String(" to ") + - QLatin1String(QMetaType::typeName(property->propType)); + QLatin1String(targetTypeName); v8::ThrowException(v8::Exception::Error(engine->toString(error))); } } @@ -1641,16 +1684,6 @@ static inline int QMetaObject_methods(const QMetaObject *metaObject) return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount; } -static QByteArray QMetaMethod_name(const QMetaMethod &m) -{ - QByteArray sig = m.signature(); - int paren = sig.indexOf('('); - if (paren == -1) - return sig; - else - return sig.left(paren); -} - /*! Returns the next related method, if one, or 0. */ @@ -1679,9 +1712,9 @@ static const QQmlPropertyData * RelatedMethod(QObject *object, dummy.load(method); // Look for overloaded methods - QByteArray methodName = QMetaMethod_name(method); + QByteArray methodName = method.name(); for (int ii = current->overrideIndex - 1; ii >= methodOffset; --ii) { - if (methodName == QMetaMethod_name(mo->method(ii))) { + if (methodName == mo->method(ii).name()) { dummy.setFlags(dummy.getFlags() | QQmlPropertyData::IsOverload); dummy.overrideIndexIsProperty = 0; dummy.overrideIndex = ii; @@ -1795,7 +1828,7 @@ static v8::Handle<v8::Value> CallOverloaded(QObject *object, const QQmlPropertyD const QQmlPropertyData *candidate = &data; while (candidate) { error += QLatin1String("\n ") + - QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).signature()); + QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).methodSignature().constData()); candidate = RelatedMethod(object, candidate, dummy); } @@ -1964,7 +1997,7 @@ void *CallArgument::dataPtr() void CallArgument::initAsType(int callType) { if (type != 0) { cleanup(); type = 0; } - if (callType == 0) return; + if (callType == QMetaType::UnknownType) return; if (callType == qMetaTypeId<QJSValue>()) { qjsValuePtr = new (&allocData) QJSValue(); @@ -1990,6 +2023,9 @@ void CallArgument::initAsType(int callType) } else if (callType == qMetaTypeId<QQmlV8Handle>()) { type = callType; handlePtr = new (&allocData) QQmlV8Handle; + } else if (callType == QMetaType::Void) { + type = -1; + qvariantPtr = new (&allocData) QVariant(); } else { type = -1; qvariantPtr = new (&allocData) QVariant(callType, (void *)0); @@ -2044,6 +2080,8 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Val } else if (callType == qMetaTypeId<QQmlV8Handle>()) { handlePtr = new (&allocData) QQmlV8Handle(QQmlV8Handle::fromHandle(value)); type = callType; + } else if (callType == QMetaType::Void) { + *qvariantPtr = QVariant(); } else { qvariantPtr = new (&allocData) QVariant(); type = -1; diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp index 7a3c675d49..cf2c13fce9 100644 --- a/src/qml/qml/v8/qv8valuetypewrapper.cpp +++ b/src/qml/qml/v8/qv8valuetypewrapper.cpp @@ -324,6 +324,13 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property QQmlBinding *newBinding = 0; if (value->IsFunction()) { + if (value->ToObject()->GetHiddenValue(r->engine->bindingFlagKey()).IsEmpty()) { + // assigning a JS function to a non-var-property is not allowed. + QString error = QLatin1String("Cannot assign JavaScript function to value-type property"); + v8::ThrowException(v8::Exception::Error(r->engine->toString(error))); + return value; + } + QQmlContextData *context = r->engine->callingContext(); v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value); diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri index 7816c84b79..52b6bf480a 100644 --- a/src/qml/qml/v8/v8.pri +++ b/src/qml/qml/v8/v8.pri @@ -15,6 +15,7 @@ HEADERS += \ $$PWD/qv8variantwrapper_p.h \ $$PWD/qv8variantresource_p.h \ $$PWD/qv8valuetypewrapper_p.h \ + $$PWD/qv8jsonwrapper_p.h \ $$PWD/qv8include_p.h \ $$PWD/qv8worker_p.h \ $$PWD/qv8bindings_p.h \ @@ -33,6 +34,7 @@ SOURCES += \ $$PWD/qv8listwrapper.cpp \ $$PWD/qv8variantwrapper.cpp \ $$PWD/qv8valuetypewrapper.cpp \ + $$PWD/qv8jsonwrapper.cpp \ $$PWD/qv8include.cpp \ $$PWD/qv8worker.cpp \ $$PWD/qv8bindings.cpp \ diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index 6567892fb4..9319cf1252 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -95,7 +95,7 @@ QT_BEGIN_NAMESPACE AnimatedImage can handle any image format supported by Qt, loaded from any URL scheme supported by Qt. - \sa QQmlImageProvider + \sa QQuickImageProvider */ /*! diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 71514593a3..b99a2f4cae 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -257,7 +257,7 @@ QQuickBorderImage::~QQuickBorderImage() The URL may be absolute, or relative to the URL of the component. - \sa QQmlImageProvider + \sa QQuickImageProvider */ /*! diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 0748dad8ed..a288531beb 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -1824,7 +1824,7 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item) if (item->clip()) { Q_ASSERT(itemPriv->clipNode() == 0); - itemPriv->extra.value().clipNode = new QQuickDefaultClipNode(item->boundingRect()); + itemPriv->extra.value().clipNode = new QQuickDefaultClipNode(item->clipRect()); itemPriv->clipNode()->update(); if (child) @@ -1916,7 +1916,7 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item) } if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode()) { - itemPriv->clipNode()->setRect(item->boundingRect()); + itemPriv->clipNode()->setRect(item->clipRect()); itemPriv->clipNode()->update(); } diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index 2346689178..64c8ba1e55 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -147,7 +147,7 @@ QQuickImagePrivate::QQuickImagePrivate() size bounded via the \l sourceSize property. This is especially important for content that is loaded from external sources or provided by the user. - \sa {declarative/imageelements/image}{Image example}, QQmlImageProvider + \sa {declarative/imageelements/image}{Image example}, QQuickImageProvider */ QQuickImage::QQuickImage(QQuickItem *parent) @@ -431,7 +431,7 @@ qreal QQuickImage::paintedHeight() const The URL may be absolute, or relative to the URL of the component. - \sa QQmlImageProvider + \sa QQuickImageProvider */ /*! diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index c5a2b447fc..ffaec540a2 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -3777,13 +3777,20 @@ void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries) /*! \internal */ // XXX todo - do we want/need this anymore? -// Note that it's now used for varying clip rect QRectF QQuickItem::boundingRect() const { Q_D(const QQuickItem); return QRectF(0, 0, d->width, d->height); } +/*! \internal */ +QRectF QQuickItem::clipRect() const +{ + Q_D(const QQuickItem); + return QRectF(0, 0, d->width, d->height); +} + + QQuickItem::TransformOrigin QQuickItem::transformOrigin() const { Q_D(const QQuickItem); @@ -6001,7 +6008,7 @@ void QQuickItemLayer::updateGeometry() { QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource; Q_ASSERT(l); - QRectF bounds = m_item->boundingRect(); + QRectF bounds = m_item->clipRect(); l->setWidth(bounds.width()); l->setHeight(bounds.height()); l->setX(bounds.x() + m_item->x()); diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 39f3fd1aea..16dee80380 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -266,6 +266,7 @@ public: void setFlags(Flags flags); virtual QRectF boundingRect() const; + virtual QRectF clipRect() const; bool hasActiveFocus() const; bool hasFocus() const; diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index 062df127b3..13c101d8a2 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -553,4 +553,9 @@ QRectF QQuickRectangle::boundingRect() const d->width + 2 * d->penMargin, d->height + 2 * d->penMargin); } +QRectF QQuickRectangle::clipRect() const +{ + return QQuickRectangle::boundingRect(); +} + QT_END_NAMESPACE diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index eec2b56fd3..52aa9e81f9 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -159,6 +159,7 @@ public: void setRadius(qreal radius); virtual QRectF boundingRect() const; + virtual QRectF clipRect() const; Q_SIGNALS: void colorChanged(); diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index 871e319380..1549057ef8 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -244,7 +244,7 @@ void QQuickShaderEffectCommon::connectPropertySignals(QQuickItem *item, Key::Sha if (!mp.hasNotifySignal()) qWarning("QQuickShaderEffect: property '%s' does not have notification method!", d.name.constData()); QByteArray signalName("2"); - signalName.append(mp.notifySignal().signature()); + signalName.append(mp.notifySignal().methodSignature()); QSignalMapper *mapper = signalMappers[shaderType].at(i); QObject::connect(item, signalName, mapper, SLOT(map())); QObject::connect(mapper, SIGNAL(mapped(int)), item, SLOT(propertyChanged(int))); diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp index 3e04a12d58..8a0c05618a 100644 --- a/src/quick/qtquick2.cpp +++ b/src/quick/qtquick2.cpp @@ -42,13 +42,14 @@ #include "qtquick2_p.h" #include <private/qqmlengine_p.h> #include <private/qquickutilmodule_p.h> -#include <private/qqmlvaluetype_p.h> +#include <private/qquickvaluetypes_p.h> #include <private/qquickitemsmodule_p.h> #include <private/qqmlenginedebugservice_p.h> #include <private/qqmldebugstatesdelegate_p.h> #include <private/qqmlbinding_p.h> #include <private/qqmlcontext_p.h> +#include <private/qquickapplication_p.h> #include <QtQuick/private/qquickpropertychanges_p.h> #include <QtQuick/private/qquickstate_p.h> #include <qqmlproperty.h> @@ -173,7 +174,10 @@ void QQmlQtQuick2Module::defineModule() QQuickUtilModule::defineModule(); QQmlEnginePrivate::defineModule(); QQuickItemsModule::defineModule(); - QQmlValueTypeFactory::registerValueTypes(); + + qmlRegisterUncreatableType<QQuickApplication>("QtQuick",2,0,"Application", QQuickApplication::tr("Application is an abstract class")); + + QQuickValueTypes::registerValueTypes(); if (QQmlEngineDebugService::isDebuggingEnabled()) { QQmlEngineDebugService::instance()->setStatesDelegate( diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 8b632661c5..da1c8e6ee9 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -56,7 +56,6 @@ #include <QOpenGLContext> #include <QtGui/qopenglframebufferobject.h> -#include <QQmlImageProvider> #include <private/qqmlglobal_p.h> #include <QtQuick/private/qsgtexture_p.h> diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h index cc7761a095..2c4531c239 100644 --- a/src/quick/scenegraph/qsgcontextplugin_p.h +++ b/src/quick/scenegraph/qsgcontextplugin_p.h @@ -43,11 +43,10 @@ #define QSGCONTEXTPLUGIN_H #include <QtQuick/qtquickglobal.h> +#include <QtQuick/qquickimageprovider.h> #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> -#include <QQmlImageProvider> - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 6b51ac596c..badbf51240 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -1766,38 +1766,19 @@ void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) } switch (type) { - case QVariant::Rect: { - variant.setValue(QQmlStringConverters::rectFFromString(variant.toString()).toRect()); - break; - } - case QVariant::RectF: { - variant.setValue(QQmlStringConverters::rectFFromString(variant.toString())); - break; - } - case QVariant::Point: { - variant.setValue(QQmlStringConverters::pointFFromString(variant.toString()).toPoint()); - break; - } - case QVariant::PointF: { - variant.setValue(QQmlStringConverters::pointFFromString(variant.toString())); - break; - } - case QVariant::Size: { - variant.setValue(QQmlStringConverters::sizeFFromString(variant.toString()).toSize()); - break; - } - case QVariant::SizeF: { - variant.setValue(QQmlStringConverters::sizeFFromString(variant.toString())); - break; - } - case QVariant::Color: { - variant.setValue(QQmlStringConverters::colorFromString(variant.toString())); - break; - } - case QVariant::Vector3D: { - variant.setValue(QQmlStringConverters::vector3DFromString(variant.toString())); + case QVariant::Rect: + case QVariant::RectF: + case QVariant::Point: + case QVariant::PointF: + case QVariant::Size: + case QVariant::SizeF: + case QVariant::Color: + case QVariant::Vector3D: + { + bool ok = false; + variant = QQmlStringConverters::variantFromString(variant.toString(), type, &ok); + } break; - } default: if (QQmlValueTypeFactory::isValueType((uint)type)) { variant.convert((QVariant::Type)type); diff --git a/src/qml/qml/qquickapplication.cpp b/src/quick/util/qquickapplication.cpp index 198a917cb8..55ebb11d29 100644 --- a/src/qml/qml/qquickapplication.cpp +++ b/src/quick/util/qquickapplication.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the QtQml module of the Qt Toolkit. +** This file is part of the QtQuick module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -40,9 +40,9 @@ ****************************************************************************/ #include "qquickapplication_p.h" + #include <private/qobject_p.h> #include <QtGui/QGuiApplication> -#include <QtGui/QInputMethod> #include <QtCore/QDebug> QT_BEGIN_NAMESPACE @@ -51,21 +51,28 @@ class QQuickApplicationPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQuickApplication) public: - QQuickApplicationPrivate() : active(QGuiApplication::activeWindow() != 0), - layoutDirection(QGuiApplication::layoutDirection()) {} - bool active; - Qt::LayoutDirection layoutDirection; + QQuickApplicationPrivate() + : isActive(QGuiApplication::focusWindow() != 0), + direction(QGuiApplication::layoutDirection()) + { + } + +private: + bool isActive; + Qt::LayoutDirection direction; }; /* This object and its properties are documented as part of the Qt object, - in qdeclarativengine.cpp + in qqmlengine.cpp */ -QQuickApplication::QQuickApplication(QObject *parent) : QObject(*new QQuickApplicationPrivate(), parent) +QQuickApplication::QQuickApplication(QObject *parent) + : QObject(*new QQuickApplicationPrivate(), parent) { - if (qApp) + if (qApp) { qApp->installEventFilter(this); + } } QQuickApplication::~QQuickApplication() @@ -75,13 +82,13 @@ QQuickApplication::~QQuickApplication() bool QQuickApplication::active() const { Q_D(const QQuickApplication); - return d->active; + return d->isActive; } Qt::LayoutDirection QQuickApplication::layoutDirection() const { Q_D(const QQuickApplication); - return d->layoutDirection; + return d->direction; } QObject *QQuickApplication::inputPanel() const @@ -91,30 +98,23 @@ QObject *QQuickApplication::inputPanel() const qWarning() << "Qt.application.inputPanel is deprecated, use Qt.inputMethod instead"; warned = true; } - return qApp ? qApp->inputMethod() : 0; + return qGuiApp->inputMethod(); } -bool QQuickApplication::eventFilter(QObject *obj, QEvent *event) +bool QQuickApplication::eventFilter(QObject *, QEvent *event) { - Q_UNUSED(obj) Q_D(QQuickApplication); - if (event->type() == QEvent::ApplicationActivate - || event->type() == QEvent::ApplicationDeactivate) { - bool active = d->active; - if (event->type() == QEvent::ApplicationActivate) - active = true; - else if (event->type() == QEvent::ApplicationDeactivate) - active = false; - - if (d->active != active) { - d->active = active; + if ((event->type() == QEvent::ApplicationActivate) || + (event->type() == QEvent::ApplicationDeactivate)) { + bool wasActive = d->isActive; + d->isActive = (event->type() == QEvent::ApplicationActivate); + if (d->isActive != wasActive) { emit activeChanged(); } - } - if (event->type() == QEvent::LayoutDirectionChange) { - Qt::LayoutDirection direction = QGuiApplication::layoutDirection(); - if (d->layoutDirection != direction) { - d->layoutDirection = direction; + } else if (event->type() == QEvent::LayoutDirectionChange) { + Qt::LayoutDirection newDirection = QGuiApplication::layoutDirection(); + if (d->direction != newDirection) { + d->direction = newDirection; emit layoutDirectionChanged(); } } diff --git a/src/qml/qml/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h index 66198948ac..e8a3cd58ca 100644 --- a/src/qml/qml/qquickapplication_p.h +++ b/src/quick/util/qquickapplication_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the QtQml module of the Qt Toolkit. +** This file is part of the QtQuick module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -44,7 +44,7 @@ #include <QtCore/QObject> #include <qqml.h> -#include <private/qtqmlglobal_p.h> +#include <private/qtquickglobal_p.h> QT_BEGIN_HEADER @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QQuickApplicationPrivate; -class Q_QML_PRIVATE_EXPORT QQuickApplication : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickApplication : public QObject { Q_OBJECT Q_PROPERTY(bool active READ active NOTIFY activeChanged) @@ -66,14 +66,13 @@ public: Qt::LayoutDirection layoutDirection() const; QT_DEPRECATED QObject *inputPanel() const; -protected: - bool eventFilter(QObject *obj, QEvent *event); - Q_SIGNALS: void activeChanged(); void layoutDirectionChanged(); private: + bool eventFilter(QObject *, QEvent *event); + Q_DISABLE_COPY(QQuickApplication) Q_DECLARE_PRIVATE(QQuickApplication) }; diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp new file mode 100644 index 0000000000..b99cb7a1d4 --- /dev/null +++ b/src/quick/util/qquickglobal.cpp @@ -0,0 +1,530 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qquickvaluetypes_p.h> +#include <private/qquickapplication_p.h> +#include <private/qqmlglobal_p.h> + +#include <QtGui/QGuiApplication> +#include <QtGui/qdesktopservices.h> +#include <QtGui/qfontdatabase.h> + + +QT_BEGIN_NAMESPACE + +class QQuickColorProvider : public QQmlColorProvider +{ +public: + static inline QColor QColorFromString(const QString &s) + { + // Should we also handle #rrggbb here? + if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) { + uchar a = fromHex(s, 1); + uchar r = fromHex(s, 3); + uchar g = fromHex(s, 5); + uchar b = fromHex(s, 7); + return QColor(r, g, b, a); + } + + return QColor(s); + } + + QVariant colorFromString(const QString &s, bool *ok) + { + QColor c(QColorFromString(s)); + if (c.isValid()) { + if (ok) *ok = true; + return QVariant(c); + } + + if (ok) *ok = false; + return QVariant(); + } + + unsigned rgbaFromString(const QString &s, bool *ok) + { + QColor c(QColorFromString(s)); + if (c.isValid()) { + if (ok) *ok = true; + return c.rgba(); + } + + if (ok) *ok = false; + return 0; + } + + QString stringFromRgba(unsigned rgba) + { + QColor c(QColor::fromRgba(rgba)); + if (c.isValid()) { + return QVariant(c).toString(); + } + + return QString(); + } + + QVariant fromRgbF(double r, double g, double b, double a) + { + return QVariant(QColor::fromRgbF(r, g, b, a)); + } + + QVariant fromHslF(double h, double s, double l, double a) + { + return QVariant(QColor::fromHslF(h, s, l, a)); + } + + QVariant lighter(const QVariant &var, qreal factor) + { + QColor color = var.value<QColor>(); + color = color.lighter(int(qRound(factor*100.))); + return QVariant::fromValue(color); + } + + QVariant darker(const QVariant &var, qreal factor) + { + QColor color = var.value<QColor>(); + color = color.darker(int(qRound(factor*100.))); + return QVariant::fromValue(color); + } + + QVariant tint(const QVariant &baseVar, const QVariant &tintVar) + { + QColor tintColor = tintVar.value<QColor>(); + + int tintAlpha = tintColor.alpha(); + if (tintAlpha == 0xFF) { + return tintVar; + } else if (tintAlpha == 0x00) { + return baseVar; + } + + // tint the base color and return the final color + QColor baseColor = baseVar.value<QColor>(); + qreal a = tintColor.alphaF(); + qreal inv_a = 1.0 - a; + + qreal r = tintColor.redF() * a + baseColor.redF() * inv_a; + qreal g = tintColor.greenF() * a + baseColor.greenF() * inv_a; + qreal b = tintColor.blueF() * a + baseColor.blueF() * inv_a; + + return QVariant::fromValue(QColor::fromRgbF(r, g, b, a + inv_a * baseColor.alphaF())); + } + +private: + static uchar fromHex(const uchar c, const uchar c2) + { + uchar rv = 0; + if (c >= '0' && c <= '9') + rv += (c - '0') * 16; + else if (c >= 'A' && c <= 'F') + rv += (c - 'A' + 10) * 16; + else if (c >= 'a' && c <= 'f') + rv += (c - 'a' + 10) * 16; + + if (c2 >= '0' && c2 <= '9') + rv += (c2 - '0'); + else if (c2 >= 'A' && c2 <= 'F') + rv += (c2 - 'A' + 10); + else if (c2 >= 'a' && c2 <= 'f') + rv += (c2 - 'a' + 10); + + return rv; + } + + static inline uchar fromHex(const QString &s, int idx) + { + uchar c = s.at(idx).toAscii(); + uchar c2 = s.at(idx + 1).toAscii(); + return fromHex(c, c2); + } +}; + + +class QQuickValueTypeProvider : public QQmlValueTypeProvider +{ +public: + static QVector3D vector3DFromString(const QString &s, bool *ok) + { + if (s.count(QLatin1Char(',')) == 2) { + int index = s.indexOf(QLatin1Char(',')); + int index2 = s.indexOf(QLatin1Char(','), index+1); + + bool xGood, yGood, zGood; + qreal xCoord = s.left(index).toDouble(&xGood); + qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood); + qreal zCoord = s.mid(index2+1).toDouble(&zGood); + + if (xGood && yGood && zGood) { + if (ok) *ok = true; + return QVector3D(xCoord, yCoord, zCoord); + } + } + + if (ok) *ok = false; + return QVector3D(); + } + + static QVector4D vector4DFromString(const QString &s, bool *ok) + { + if (s.count(QLatin1Char(',')) == 3) { + int index = s.indexOf(QLatin1Char(',')); + int index2 = s.indexOf(QLatin1Char(','), index+1); + int index3 = s.indexOf(QLatin1Char(','), index2+1); + + bool xGood, yGood, zGood, wGood; + qreal xCoord = s.left(index).toDouble(&xGood); + qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood); + qreal zCoord = s.mid(index2+1, index3-index2-1).toDouble(&zGood); + qreal wCoord = s.mid(index3+1).toDouble(&wGood); + + if (xGood && yGood && zGood && wGood) { + if (ok) *ok = true; + return QVector4D(xCoord, yCoord, zCoord, wCoord); + } + } + + if (ok) *ok = false; + return QVector4D(); + } + + bool create(int type, QQmlValueType *&v) + { + switch (type) { + case QMetaType::QColor: + v = new QQuickColorValueType; + return true; + case QMetaType::QVector2D: + v = new QQuickVector2DValueType; + return true; + case QMetaType::QVector3D: + v = new QQuickVector3DValueType; + return true; + case QMetaType::QVector4D: + v = new QQuickVector4DValueType; + return true; + case QMetaType::QQuaternion: + v = new QQuickQuaternionValueType; + return true; + case QMetaType::QMatrix4x4: + v = new QQuickMatrix4x4ValueType; + return true; + case QMetaType::QFont: + v = new QQuickFontValueType; + return true; + default: + return false; + } + } + + bool init(int type, void *data, size_t n) + { + if (type == QMetaType::QColor) { + Q_ASSERT(n >= sizeof(QColor)); + QColor *color = reinterpret_cast<QColor *>(data); + new (color) QColor(); + return true; + } + + return false; + } + + bool destroy(int type, void *data, size_t n) + { + if (type == QMetaType::QColor) { + Q_ASSERT(n >= sizeof(QColor)); + QColor *color = reinterpret_cast<QColor *>(data); + color->~QColor(); + return true; + } + + return false; + } + + bool copy(int type, const void *src, void *dst, size_t n) + { + if (type == QMetaType::QColor) { + Q_ASSERT(n >= sizeof(QColor)); + const QColor *srcColor = reinterpret_cast<const QColor *>(src); + QColor *dstColor = reinterpret_cast<QColor *>(dst); + new (dstColor) QColor(*srcColor); + return true; + } + + return false; + } + + bool create(int type, int argc, const void *argv[], QVariant *v) + { + switch (type) { + case QMetaType::QVector3D: + if (argc == 1) { + const float *xyz = reinterpret_cast<const float*>(argv[0]); + QVector3D v3(xyz[0], xyz[1], xyz[2]); + *v = QVariant(v3); + return true; + } + break; + case QMetaType::QVector4D: + if (argc == 1) { + const float *xyzw = reinterpret_cast<const float*>(argv[0]); + QVector4D v4(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); + *v = QVariant(v4); + return true; + } + break; + } + + return false; + } + + bool createFromString(int type, const QString &s, void *data, size_t n) + { + bool ok = false; + + switch (type) { + case QMetaType::QColor: + { + Q_ASSERT(n >= sizeof(QColor)); + QColor *color = reinterpret_cast<QColor *>(data); + new (color) QColor(QQuickColorProvider::QColorFromString(s)); + return true; + } + case QMetaType::QVector3D: + { + Q_ASSERT(n >= sizeof(QVector3D)); + QVector3D *v3 = reinterpret_cast<QVector3D *>(data); + new (v3) QVector3D(vector3DFromString(s, &ok)); + return true; + } + case QMetaType::QVector4D: + { + Q_ASSERT(n >= sizeof(QVector4D)); + QVector4D *v4 = reinterpret_cast<QVector4D *>(data); + new (v4) QVector4D(vector4DFromString(s, &ok)); + return true; + } + } + + return false; + } + + bool createStringFrom(int type, const void *data, QString *s) + { + if (type == QMetaType::QColor) { + const QColor *color = reinterpret_cast<const QColor *>(data); + new (s) QString(QVariant(*color).toString()); + return true; + } + + return false; + } + + bool variantFromString(const QString &s, QVariant *v) + { + QColor c(QQuickColorProvider::QColorFromString(s)); + if (c.isValid()) { + *v = QVariant::fromValue(c); + return true; + } + + bool ok = false; + + QVector3D v3 = vector3DFromString(s, &ok); + if (ok) { + *v = QVariant::fromValue(v3); + return true; + } + + QVector4D v4 = vector4DFromString(s, &ok); + if (ok) { + *v = QVariant::fromValue(v4); + return true; + } + + return false; + } + + bool variantFromString(int type, const QString &s, QVariant *v) + { + bool ok = false; + + switch (type) { + case QMetaType::QColor: + { + QColor c(QQuickColorProvider::QColorFromString(s)); + *v = QVariant::fromValue(c); + return true; + } + case QMetaType::QVector3D: + *v = QVariant::fromValue(vector3DFromString(s, &ok)); + return true; + case QMetaType::QVector4D: + *v = QVariant::fromValue(vector4DFromString(s, &ok)); + return true; + } + + return false; + } + + bool store(int type, const void *src, void *dst, size_t n) + { + switch (type) { + case QMetaType::QColor: + { + Q_ASSERT(n >= sizeof(QColor)); + const QRgb *rgb = reinterpret_cast<const QRgb *>(src); + QColor *color = reinterpret_cast<QColor *>(dst); + new (color) QColor(QColor::fromRgba(*rgb)); + return true; + } + case QMetaType::QVector3D: + { + Q_ASSERT(n >= sizeof(QVector3D)); + const QVector3D *srcVector = reinterpret_cast<const QVector3D *>(src); + QVector3D *dstVector = reinterpret_cast<QVector3D *>(dst); + new (dstVector) QVector3D(*srcVector); + return true; + } + case QMetaType::QVector4D: + { + Q_ASSERT(n >= sizeof(QVector4D)); + const QVector4D *srcVector = reinterpret_cast<const QVector4D *>(src); + QVector4D *dstVector = reinterpret_cast<QVector4D *>(dst); + new (dstVector) QVector4D(*srcVector); + return true; + } + } + + return false; + } + + bool read(int srcType, const void *src, int dstType, void *dst) + { + if (dstType == QMetaType::QColor) { + QColor *dstColor = reinterpret_cast<QColor *>(dst); + if (srcType == QMetaType::QColor) { + const QColor *srcColor = reinterpret_cast<const QColor *>(src); + *dstColor = *srcColor; + } else { + *dstColor = QColor(); + } + return true; + } + + return false; + } + + bool write(int type, const void *src, void *dst, size_t n) + { + if (type == QMetaType::QColor) { + Q_ASSERT(n >= sizeof(QColor)); + const QColor *srcColor = reinterpret_cast<const QColor *>(src); + QColor *dstColor = reinterpret_cast<QColor *>(dst); + if (*dstColor != *srcColor) { + *dstColor = *srcColor; + return true; + } + } + + return false; + } +}; + + +class QQuickGuiProvider : public QQmlGuiProvider +{ +public: + QQuickApplication *application(QObject *parent) + { + return new QQuickApplication(parent); + } + + QInputMethod *inputMethod() + { + return qGuiApp->inputMethod(); + } + + QStringList fontFamilies() + { + QFontDatabase database; + return database.families(); + } + + bool openUrlExternally(QUrl &url) + { +#ifndef QT_NO_DESKTOPSERVICES + return QDesktopServices::openUrl(url); +#else + return false; +#endif + } +}; + + +static QQuickValueTypeProvider *getValueTypeProvider() +{ + static QQuickValueTypeProvider valueTypeProvider; + return &valueTypeProvider; +} + +static QQuickColorProvider *getColorProvider() +{ + static QQuickColorProvider colorProvider; + return &colorProvider; +} + +static QQuickGuiProvider *getGuiProvider() +{ + static QQuickGuiProvider guiProvider; + return &guiProvider; +} + +static bool initializeProviders() +{ + QQml_addValueTypeProvider(getValueTypeProvider()); + QQml_setColorProvider(getColorProvider()); + QQml_setGuiProvider(getGuiProvider()); + return true; +} + +static bool initialized = initializeProviders(); + +QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index 5742b00de3..b306ab3419 100644 --- a/src/qml/qml/qqmlimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -39,14 +39,14 @@ ** ****************************************************************************/ -#include "qqmlimageprovider.h" +#include "qquickimageprovider.h" QT_BEGIN_NAMESPACE -class QQmlImageProviderPrivate +class QQuickImageProviderPrivate { public: - QQmlImageProvider::ImageType type; + QQuickImageProvider::ImageType type; }; /*! @@ -110,12 +110,12 @@ QImage QQuickTextureFactory::image() const /*! - \class QQmlImageProvider + \class QQuickImageProvider \since 5.0 - \inmodule QtQml - \brief The QQmlImageProvider class provides an interface for supporting pixmaps and threaded image requests in QML. + \inmodule QtQuick + \brief The QQuickImageProvider class provides an interface for supporting pixmaps and threaded image requests in QML. - QQmlImageProvider is used to provide advanced image loading features + QQuickImageProvider is used to provide advanced image loading features in QML applications. It allows images in QML to be: \list @@ -212,7 +212,7 @@ QImage QQuickTextureFactory::image() const \section2 Image caching - Images returned by a QQmlImageProvider are automatically cached, + Images returned by a QQuickImageProvider are automatically cached, similar to any image loaded by the QML engine. When an image with a "image://" prefix is loaded from cache, requestImage() and requestPixmap() will not be called for the relevant image provider. If an image should always @@ -226,33 +226,20 @@ QImage QQuickTextureFactory::image() const */ /*! - \enum QQmlImageProvider::ImageType - - Defines the type of image supported by this image provider. - - \value Image The Image Provider provides QImage images. The - requestImage() method will be called for all image requests. - \value Pixmap The Image Provider provides QPixmap images. The - requestPixmap() method will be called for all image requests. - \value Texture The Image Provider provides QSGTextureProvider based images. - The requestTexture() method will be called for all image requests. \omitvalue -*/ - -/*! Creates an image provider that will provide images of the given \a type. */ -QQmlImageProvider::QQmlImageProvider(ImageType type) - : d(new QQmlImageProviderPrivate) +QQuickImageProvider::QQuickImageProvider(ImageType type) + : d(new QQuickImageProviderPrivate) { d->type = type; } /*! - Destroys the QQmlImageProvider + Destroys the QQuickImageProvider \note The destructor of your derived class need to be thread safe. */ -QQmlImageProvider::~QQmlImageProvider() +QQuickImageProvider::~QQuickImageProvider() { delete d; } @@ -260,7 +247,7 @@ QQmlImageProvider::~QQmlImageProvider() /*! Returns the image type supported by this provider. */ -QQmlImageProvider::ImageType QQmlImageProvider::imageType() const +QQuickImageProvider::ImageType QQuickImageProvider::imageType() const { return d->type; } @@ -284,7 +271,7 @@ QQmlImageProvider::ImageType QQmlImageProvider::imageType() const \note this method may be called by multiple threads, so ensure the implementation of this method is reentrant. */ -QImage QQmlImageProvider::requestImage(const QString &id, QSize *size, const QSize& requestedSize) +QImage QQuickImageProvider::requestImage(const QString &id, QSize *size, const QSize& requestedSize) { Q_UNUSED(id); Q_UNUSED(size); @@ -310,7 +297,7 @@ QImage QQmlImageProvider::requestImage(const QString &id, QSize *size, const QSi is used to set the \l {Item::}{width} and \l {Item::}{height} of the relevant \l Image if these values have not been set explicitly. */ -QPixmap QQmlImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) +QPixmap QQuickImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) { Q_UNUSED(id); Q_UNUSED(size); @@ -341,7 +328,7 @@ QPixmap QQmlImageProvider::requestPixmap(const QString &id, QSize *size, const Q implementation of this method is reentrant. */ -QQuickTextureFactory *QQmlImageProvider::requestTexture(const QString &id, QSize *size, const QSize &requestedSize) +QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSize *size, const QSize &requestedSize) { Q_UNUSED(id); Q_UNUSED(size); diff --git a/src/qml/qml/qqmlimageprovider.h b/src/quick/util/qquickimageprovider.h index da4d8c8248..252d57b1d6 100644 --- a/src/qml/qml/qqmlimageprovider.h +++ b/src/quick/util/qquickimageprovider.h @@ -39,23 +39,24 @@ ** ****************************************************************************/ -#ifndef QQMLIMAGEPROVIDER_H -#define QQMLIMAGEPROVIDER_H +#ifndef QQUICKIMAGEPROVIDER_H +#define QQUICKIMAGEPROVIDER_H -#include <QtQml/qtqmlglobal.h> +#include <QtQuick/qtquickglobal.h> #include <QtGui/qimage.h> #include <QtGui/qpixmap.h> +#include <QtQml/qqmlengine.h> QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQmlImageProviderPrivate; +class QQuickImageProviderPrivate; class QSGTexture; class QQuickCanvas; -class Q_QML_EXPORT QQuickTextureFactory : public QObject +class Q_QUICK_EXPORT QQuickTextureFactory : public QObject { public: QQuickTextureFactory(); @@ -67,18 +68,11 @@ public: virtual QImage image() const; }; -class Q_QML_EXPORT QQmlImageProvider +class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase { public: - enum ImageType { - Image, - Pixmap, - Texture, - Invalid - }; - - QQmlImageProvider(ImageType type); - virtual ~QQmlImageProvider(); + QQuickImageProvider(ImageType type); + virtual ~QQuickImageProvider(); ImageType imageType() const; @@ -87,11 +81,11 @@ public: virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize); private: - QQmlImageProviderPrivate *d; + QQuickImageProviderPrivate *d; }; QT_END_NAMESPACE QT_END_HEADER -#endif // QQMLIMAGEPROVIDER +#endif // QQUICKIMAGEPROVIDER_H diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 9185fba343..801b007cdd 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -41,7 +41,7 @@ #include "qquickpixmapcache_p.h" #include <qqmlnetworkaccessmanagerfactory.h> -#include <qqmlimageprovider.h> +#include <qquickimageprovider.h> #include <qqmlengine.h> #include <private/qqmlglobal_p.h> @@ -76,6 +76,16 @@ QT_BEGIN_NAMESPACE // The cache limit describes the maximum "junk" in the cache. static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded in qpixmapcache.cpp +static inline QString imageProviderId(const QUrl &url) +{ + return url.host(); +} + +static inline QString imageId(const QUrl &url) +{ + return url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1); +} + QSGTexture *QQuickDefaultTextureFactory::createTexture(QQuickCanvas *) const { QSGPlainTexture *t = new QSGPlainTexture(); @@ -502,11 +512,15 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u { // fetch if (url.scheme() == QLatin1String("image")) { - // Use QmlImageProvider + // Use QQuickImageProvider QSize readSize; - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - QQmlImageProvider::ImageType imageType = ep->getImageProviderType(url); - if (imageType == QQmlImageProvider::Invalid) { + + QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid; + QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url))); + if (provider) + imageType = provider->imageType(); + + if (imageType == QQuickImageProvider::Invalid) { QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::Loading; QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString()); QImage image; @@ -514,8 +528,8 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u if (!cancelled.contains(runningJob)) runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image)); mutex.unlock(); - } else if (imageType == QQmlImageProvider::Image) { - QImage image = ep->getImageFromProvider(url, &readSize, requestSize); + } else if (imageType == QQuickImageProvider::Image) { + QImage image = provider->requestImage(imageId(url), &readSize, requestSize); QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError; QString errorStr; if (image.isNull()) { @@ -527,7 +541,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image)); mutex.unlock(); } else { - QQuickTextureFactory *t = ep->getTextureFromProvider(url, &readSize, requestSize); + QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, requestSize); QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError; QString errorStr; if (!t) { @@ -919,33 +933,36 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q { if (url.scheme() == QLatin1String("image")) { QSize readSize; - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - QQmlImageProvider::ImageType imageType = ep->getImageProviderType(url); + + QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid; + QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url))); + if (provider) + imageType = provider->imageType(); switch (imageType) { - case QQmlImageProvider::Invalid: + case QQuickImageProvider::Invalid: return new QQuickPixmapData(declarativePixmap, url, requestSize, QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString())); - case QQmlImageProvider::Texture: + case QQuickImageProvider::Texture: { - QQuickTextureFactory *texture = ep->getTextureFromProvider(url, &readSize, requestSize); + QQuickTextureFactory *texture = provider->requestTexture(imageId(url), &readSize, requestSize); if (texture) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize); } } - case QQmlImageProvider::Image: + case QQuickImageProvider::Image: { - QImage image = ep->getImageFromProvider(url, &readSize, requestSize); + QImage image = provider->requestImage(imageId(url), &readSize, requestSize); if (!image.isNull()) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize); } } - case QQmlImageProvider::Pixmap: + case QQuickImageProvider::Pixmap: { - QPixmap pixmap = ep->getPixmapFromProvider(url, &readSize, requestSize); + QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize); if (!pixmap.isNull()) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(pixmap.toImage()), readSize, requestSize); @@ -1152,9 +1169,11 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (iter == store->m_cache.end()) { if (options & QQuickPixmap::Asynchronous) { // pixmaps can only be loaded synchronously - if (url.scheme() == QLatin1String("image") - && QQmlEnginePrivate::get(engine)->getImageProviderType(url) == QQmlImageProvider::Pixmap) { - options &= ~QQuickPixmap::Asynchronous; + if (url.scheme() == QLatin1String("image")) { + QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url))); + if (provider && provider->imageType() == QQuickImageProvider::Pixmap) { + options &= ~QQuickPixmap::Asynchronous; + } } } diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h index b339e6f1a0..03f2e65cc2 100644 --- a/src/quick/util/qquickpixmapcache_p.h +++ b/src/quick/util/qquickpixmapcache_p.h @@ -47,9 +47,9 @@ #include <QtGui/qpixmap.h> #include <QtCore/qurl.h> #include <QtQuick/qtquickglobal.h> +#include <QtQuick/qquickimageprovider.h> #include <private/qintrusivelist_p.h> -#include <qqmlimageprovider.h> QT_BEGIN_HEADER diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp new file mode 100644 index 0000000000..179f840acd --- /dev/null +++ b/src/quick/util/qquickvaluetypes.cpp @@ -0,0 +1,468 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qquickvaluetypes_p.h> + +#include <qtquickglobal.h> +#include <private/qqmlvaluetype_p.h> +#include <private/qfont_p.h> + + +QT_BEGIN_NAMESPACE + +namespace QQuickValueTypes { + +void registerValueTypes() +{ + QQmlValueTypeFactory::registerValueTypes(); + + qmlRegisterValueTypeEnums<QQuickFontValueType>("QtQuick", 2, 0, "Font"); +} + +} + +QQuickColorValueType::QQuickColorValueType(QObject *parent) + : QQmlValueTypeBase<QColor>(parent) +{ +} + +QString QQuickColorValueType::toString() const +{ + // to maintain behaviour with QtQuick 1.0, we just output normal toString() value. + return QVariant(v).toString(); +} + +qreal QQuickColorValueType::r() const +{ + return v.redF(); +} + +qreal QQuickColorValueType::g() const +{ + return v.greenF(); +} + +qreal QQuickColorValueType::b() const +{ + return v.blueF(); +} + +qreal QQuickColorValueType::a() const +{ + return v.alphaF(); +} + +void QQuickColorValueType::setR(qreal r) +{ + v.setRedF(r); +} + +void QQuickColorValueType::setG(qreal g) +{ + v.setGreenF(g); +} + +void QQuickColorValueType::setB(qreal b) +{ + v.setBlueF(b); +} + +void QQuickColorValueType::setA(qreal a) +{ + v.setAlphaF(a); +} + + +QQuickVector2DValueType::QQuickVector2DValueType(QObject *parent) + : QQmlValueTypeBase<QVector2D>(parent) +{ +} + +QString QQuickVector2DValueType::toString() const +{ + return QString(QLatin1String("QVector2D(%1, %2)")).arg(v.x()).arg(v.y()); +} + +qreal QQuickVector2DValueType::x() const +{ + return v.x(); +} + +qreal QQuickVector2DValueType::y() const +{ + return v.y(); +} + +void QQuickVector2DValueType::setX(qreal x) +{ + v.setX(x); +} + +void QQuickVector2DValueType::setY(qreal y) +{ + v.setY(y); +} + + +QQuickVector3DValueType::QQuickVector3DValueType(QObject *parent) + : QQmlValueTypeBase<QVector3D>(parent) +{ +} + +QString QQuickVector3DValueType::toString() const +{ + return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(v.x()).arg(v.y()).arg(v.z()); +} + +qreal QQuickVector3DValueType::x() const +{ + return v.x(); +} + +qreal QQuickVector3DValueType::y() const +{ + return v.y(); +} + +qreal QQuickVector3DValueType::z() const +{ + return v.z(); +} + +void QQuickVector3DValueType::setX(qreal x) +{ + v.setX(x); +} + +void QQuickVector3DValueType::setY(qreal y) +{ + v.setY(y); +} + +void QQuickVector3DValueType::setZ(qreal z) +{ + v.setZ(z); +} + + +QQuickVector4DValueType::QQuickVector4DValueType(QObject *parent) + : QQmlValueTypeBase<QVector4D>(parent) +{ +} + +QString QQuickVector4DValueType::toString() const +{ + return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.z()).arg(v.w()); +} + +qreal QQuickVector4DValueType::x() const +{ + return v.x(); +} + +qreal QQuickVector4DValueType::y() const +{ + return v.y(); +} + +qreal QQuickVector4DValueType::z() const +{ + return v.z(); +} + +qreal QQuickVector4DValueType::w() const +{ + return v.w(); +} + +void QQuickVector4DValueType::setX(qreal x) +{ + v.setX(x); +} + +void QQuickVector4DValueType::setY(qreal y) +{ + v.setY(y); +} + +void QQuickVector4DValueType::setZ(qreal z) +{ + v.setZ(z); +} + +void QQuickVector4DValueType::setW(qreal w) +{ + v.setW(w); +} + + +QQuickQuaternionValueType::QQuickQuaternionValueType(QObject *parent) + : QQmlValueTypeBase<QQuaternion>(parent) +{ +} + +QString QQuickQuaternionValueType::toString() const +{ + return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(v.scalar()).arg(v.x()).arg(v.y()).arg(v.z()); +} + +qreal QQuickQuaternionValueType::scalar() const +{ + return v.scalar(); +} + +qreal QQuickQuaternionValueType::x() const +{ + return v.x(); +} + +qreal QQuickQuaternionValueType::y() const +{ + return v.y(); +} + +qreal QQuickQuaternionValueType::z() const +{ + return v.z(); +} + +void QQuickQuaternionValueType::setScalar(qreal scalar) +{ + v.setScalar(scalar); +} + +void QQuickQuaternionValueType::setX(qreal x) +{ + v.setX(x); +} + +void QQuickQuaternionValueType::setY(qreal y) +{ + v.setY(y); +} + +void QQuickQuaternionValueType::setZ(qreal z) +{ + v.setZ(z); +} + + +QQuickMatrix4x4ValueType::QQuickMatrix4x4ValueType(QObject *parent) + : QQmlValueTypeBase<QMatrix4x4>(parent) +{ +} + +QString QQuickMatrix4x4ValueType::toString() const +{ + return QString(QLatin1String("QMatrix4x4(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16)")) + .arg(v(0, 0)).arg(v(0, 1)).arg(v(0, 2)).arg(v(0, 3)) + .arg(v(1, 0)).arg(v(1, 1)).arg(v(1, 2)).arg(v(1, 3)) + .arg(v(2, 0)).arg(v(2, 1)).arg(v(2, 2)).arg(v(2, 3)) + .arg(v(3, 0)).arg(v(3, 1)).arg(v(3, 2)).arg(v(3, 3)); +} + + +QQuickFontValueType::QQuickFontValueType(QObject *parent) + : QQmlValueTypeBase<QFont>(parent), + pixelSizeSet(false), + pointSizeSet(false) +{ +} + +void QQuickFontValueType::onLoad() +{ + pixelSizeSet = false; + pointSizeSet = false; +} + +QString QQuickFontValueType::toString() const +{ + return QString(QLatin1String("QFont(%1)")).arg(v.toString()); +} + +QString QQuickFontValueType::family() const +{ + return v.family(); +} + +void QQuickFontValueType::setFamily(const QString &family) +{ + v.setFamily(family); +} + +bool QQuickFontValueType::bold() const +{ + return v.bold(); +} + +void QQuickFontValueType::setBold(bool b) +{ + v.setBold(b); +} + +QQuickFontValueType::FontWeight QQuickFontValueType::weight() const +{ + return (QQuickFontValueType::FontWeight)v.weight(); +} + +void QQuickFontValueType::setWeight(QQuickFontValueType::FontWeight w) +{ + v.setWeight((QFont::Weight)w); +} + +bool QQuickFontValueType::italic() const +{ + return v.italic(); +} + +void QQuickFontValueType::setItalic(bool b) +{ + v.setItalic(b); +} + +bool QQuickFontValueType::underline() const +{ + return v.underline(); +} + +void QQuickFontValueType::setUnderline(bool b) +{ + v.setUnderline(b); +} + +bool QQuickFontValueType::overline() const +{ + return v.overline(); +} + +void QQuickFontValueType::setOverline(bool b) +{ + v.setOverline(b); +} + +bool QQuickFontValueType::strikeout() const +{ + return v.strikeOut(); +} + +void QQuickFontValueType::setStrikeout(bool b) +{ + v.setStrikeOut(b); +} + +qreal QQuickFontValueType::pointSize() const +{ + if (v.pointSizeF() == -1) { + if (dpi.isNull) + dpi = qt_defaultDpi(); + return v.pixelSize() * qreal(72.) / qreal(dpi); + } + return v.pointSizeF(); +} + +void QQuickFontValueType::setPointSize(qreal size) +{ + if (pixelSizeSet) { + qWarning() << "Both point size and pixel size set. Using pixel size."; + return; + } + + if (size >= 0.0) { + pointSizeSet = true; + v.setPointSizeF(size); + } else { + pointSizeSet = false; + } +} + +int QQuickFontValueType::pixelSize() const +{ + if (v.pixelSize() == -1) { + if (dpi.isNull) + dpi = qt_defaultDpi(); + return (v.pointSizeF() * dpi) / qreal(72.); + } + return v.pixelSize(); +} + +void QQuickFontValueType::setPixelSize(int size) +{ + if (size >0) { + if (pointSizeSet) + qWarning() << "Both point size and pixel size set. Using pixel size."; + v.setPixelSize(size); + pixelSizeSet = true; + } else { + pixelSizeSet = false; + } +} + +QQuickFontValueType::Capitalization QQuickFontValueType::capitalization() const +{ + return (QQuickFontValueType::Capitalization)v.capitalization(); +} + +void QQuickFontValueType::setCapitalization(QQuickFontValueType::Capitalization c) +{ + v.setCapitalization((QFont::Capitalization)c); +} + +qreal QQuickFontValueType::letterSpacing() const +{ + return v.letterSpacing(); +} + +void QQuickFontValueType::setLetterSpacing(qreal size) +{ + v.setLetterSpacing(QFont::AbsoluteSpacing, size); +} + +qreal QQuickFontValueType::wordSpacing() const +{ + return v.wordSpacing(); +} + +void QQuickFontValueType::setWordSpacing(qreal size) +{ + v.setWordSpacing(size); +} + +QT_END_NAMESPACE diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h new file mode 100644 index 0000000000..d2767db329 --- /dev/null +++ b/src/quick/util/qquickvaluetypes_p.h @@ -0,0 +1,310 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKVALUETYPES_P_H +#define QQUICKVALUETYPES_P_H + +#include <qqml.h> +#include <qtquickglobal.h> +#include <private/qqmlvaluetype_p.h> + +#include <QtGui/QColor> +#include <QtGui/QVector2D> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> +#include <QtGui/QQuaternion> +#include <QtGui/QMatrix4x4> +#include <QtGui/QFont> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QQuickValueTypes { + +void registerValueTypes(); + +} + +class Q_AUTOTEST_EXPORT QQuickColorValueType : public QQmlValueTypeBase<QColor> +{ + Q_PROPERTY(qreal r READ r WRITE setR) + Q_PROPERTY(qreal g READ g WRITE setG) + Q_PROPERTY(qreal b READ b WRITE setB) + Q_PROPERTY(qreal a READ a WRITE setA) + Q_OBJECT +public: + QQuickColorValueType(QObject *parent = 0); + + virtual QString toString() const; + + qreal r() const; + qreal g() const; + qreal b() const; + qreal a() const; + void setR(qreal); + void setG(qreal); + void setB(qreal); + void setA(qreal); +}; + +class Q_AUTOTEST_EXPORT QQuickVector2DValueType : public QQmlValueTypeBase<QVector2D> +{ + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_OBJECT +public: + QQuickVector2DValueType(QObject *parent = 0); + + virtual QString toString() const; + + qreal x() const; + qreal y() const; + void setX(qreal); + void setY(qreal); +}; + +class Q_AUTOTEST_EXPORT QQuickVector3DValueType : public QQmlValueTypeBase<QVector3D> +{ + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_PROPERTY(qreal z READ z WRITE setZ) + Q_OBJECT +public: + QQuickVector3DValueType(QObject *parent = 0); + + virtual QString toString() const; + + qreal x() const; + qreal y() const; + qreal z() const; + void setX(qreal); + void setY(qreal); + void setZ(qreal); +}; + +class Q_AUTOTEST_EXPORT QQuickVector4DValueType : public QQmlValueTypeBase<QVector4D> +{ + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_PROPERTY(qreal z READ z WRITE setZ) + Q_PROPERTY(qreal w READ w WRITE setW) + Q_OBJECT +public: + QQuickVector4DValueType(QObject *parent = 0); + + virtual QString toString() const; + + qreal x() const; + qreal y() const; + qreal z() const; + qreal w() const; + void setX(qreal); + void setY(qreal); + void setZ(qreal); + void setW(qreal); +}; + +class Q_AUTOTEST_EXPORT QQuickQuaternionValueType : public QQmlValueTypeBase<QQuaternion> +{ + Q_PROPERTY(qreal scalar READ scalar WRITE setScalar) + Q_PROPERTY(qreal x READ x WRITE setX) + Q_PROPERTY(qreal y READ y WRITE setY) + Q_PROPERTY(qreal z READ z WRITE setZ) + Q_OBJECT +public: + QQuickQuaternionValueType(QObject *parent = 0); + + virtual QString toString() const; + + qreal scalar() const; + qreal x() const; + qreal y() const; + qreal z() const; + void setScalar(qreal); + void setX(qreal); + void setY(qreal); + void setZ(qreal); +}; + +class Q_AUTOTEST_EXPORT QQuickMatrix4x4ValueType : public QQmlValueTypeBase<QMatrix4x4> +{ + Q_PROPERTY(qreal m11 READ m11 WRITE setM11) + Q_PROPERTY(qreal m12 READ m12 WRITE setM12) + Q_PROPERTY(qreal m13 READ m13 WRITE setM13) + Q_PROPERTY(qreal m14 READ m14 WRITE setM14) + Q_PROPERTY(qreal m21 READ m21 WRITE setM21) + Q_PROPERTY(qreal m22 READ m22 WRITE setM22) + Q_PROPERTY(qreal m23 READ m23 WRITE setM23) + Q_PROPERTY(qreal m24 READ m24 WRITE setM24) + Q_PROPERTY(qreal m31 READ m31 WRITE setM31) + Q_PROPERTY(qreal m32 READ m32 WRITE setM32) + Q_PROPERTY(qreal m33 READ m33 WRITE setM33) + Q_PROPERTY(qreal m34 READ m34 WRITE setM34) + Q_PROPERTY(qreal m41 READ m41 WRITE setM41) + Q_PROPERTY(qreal m42 READ m42 WRITE setM42) + Q_PROPERTY(qreal m43 READ m43 WRITE setM43) + Q_PROPERTY(qreal m44 READ m44 WRITE setM44) + Q_OBJECT +public: + QQuickMatrix4x4ValueType(QObject *parent = 0); + + virtual QString toString() const; + + qreal m11() const { return v(0, 0); } + qreal m12() const { return v(0, 1); } + qreal m13() const { return v(0, 2); } + qreal m14() const { return v(0, 3); } + qreal m21() const { return v(1, 0); } + qreal m22() const { return v(1, 1); } + qreal m23() const { return v(1, 2); } + qreal m24() const { return v(1, 3); } + qreal m31() const { return v(2, 0); } + qreal m32() const { return v(2, 1); } + qreal m33() const { return v(2, 2); } + qreal m34() const { return v(2, 3); } + qreal m41() const { return v(3, 0); } + qreal m42() const { return v(3, 1); } + qreal m43() const { return v(3, 2); } + qreal m44() const { return v(3, 3); } + + void setM11(qreal value) { v(0, 0) = value; } + void setM12(qreal value) { v(0, 1) = value; } + void setM13(qreal value) { v(0, 2) = value; } + void setM14(qreal value) { v(0, 3) = value; } + void setM21(qreal value) { v(1, 0) = value; } + void setM22(qreal value) { v(1, 1) = value; } + void setM23(qreal value) { v(1, 2) = value; } + void setM24(qreal value) { v(1, 3) = value; } + void setM31(qreal value) { v(2, 0) = value; } + void setM32(qreal value) { v(2, 1) = value; } + void setM33(qreal value) { v(2, 2) = value; } + void setM34(qreal value) { v(2, 3) = value; } + void setM41(qreal value) { v(3, 0) = value; } + void setM42(qreal value) { v(3, 1) = value; } + void setM43(qreal value) { v(3, 2) = value; } + void setM44(qreal value) { v(3, 3) = value; } +}; + +class Q_AUTOTEST_EXPORT QQuickFontValueType : public QQmlValueTypeBase<QFont> +{ + Q_OBJECT + Q_ENUMS(FontWeight) + Q_ENUMS(Capitalization) + + Q_PROPERTY(QString family READ family WRITE setFamily) + Q_PROPERTY(bool bold READ bold WRITE setBold) + Q_PROPERTY(FontWeight weight READ weight WRITE setWeight) + Q_PROPERTY(bool italic READ italic WRITE setItalic) + Q_PROPERTY(bool underline READ underline WRITE setUnderline) + Q_PROPERTY(bool overline READ overline WRITE setOverline) + Q_PROPERTY(bool strikeout READ strikeout WRITE setStrikeout) + Q_PROPERTY(qreal pointSize READ pointSize WRITE setPointSize) + Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize) + Q_PROPERTY(Capitalization capitalization READ capitalization WRITE setCapitalization) + Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing) + Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing) + +public: + enum FontWeight { Light = QFont::Light, + Normal = QFont::Normal, + DemiBold = QFont::DemiBold, + Bold = QFont::Bold, + Black = QFont::Black }; + enum Capitalization { MixedCase = QFont::MixedCase, + AllUppercase = QFont::AllUppercase, + AllLowercase = QFont::AllLowercase, + SmallCaps = QFont::SmallCaps, + Capitalize = QFont::Capitalize }; + + QQuickFontValueType(QObject *parent = 0); + + virtual QString toString() const; + + QString family() const; + void setFamily(const QString &); + + bool bold() const; + void setBold(bool b); + + FontWeight weight() const; + void setWeight(FontWeight); + + bool italic() const; + void setItalic(bool b); + + bool underline() const; + void setUnderline(bool b); + + bool overline() const; + void setOverline(bool b); + + bool strikeout() const; + void setStrikeout(bool b); + + qreal pointSize() const; + void setPointSize(qreal size); + + int pixelSize() const; + void setPixelSize(int size); + + Capitalization capitalization() const; + void setCapitalization(Capitalization); + + qreal letterSpacing() const; + void setLetterSpacing(qreal spacing); + + qreal wordSpacing() const; + void setWordSpacing(qreal spacing); + + void onLoad(); + +private: + bool pixelSizeSet; + bool pointSizeSet; + mutable QQmlNullableValue<int> dpi; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QQUICKVALUETYPES_P_H diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri index c3cec91404..3d93b9f2f5 100644 --- a/src/quick/util/util.pri +++ b/src/quick/util/util.pri @@ -1,4 +1,5 @@ SOURCES += \ + $$PWD/qquickapplication.cpp\ $$PWD/qquickutilmodule.cpp\ $$PWD/qquickconnections.cpp \ $$PWD/qquickpackage.cpp \ @@ -25,9 +26,13 @@ SOURCES += \ $$PWD/qquickchangeset.cpp \ $$PWD/qquicklistcompositor.cpp \ $$PWD/qquickpathinterpolator.cpp \ - $$PWD/qquicksvgparser.cpp + $$PWD/qquickimageprovider.cpp \ + $$PWD/qquicksvgparser.cpp \ + $$PWD/qquickvaluetypes.cpp \ + $$PWD/qquickglobal.cpp HEADERS += \ + $$PWD/qquickapplication_p.h\ $$PWD/qquickutilmodule_p.h\ $$PWD/qquickconnections_p.h \ $$PWD/qquickpackage_p.h \ @@ -58,4 +63,6 @@ HEADERS += \ $$PWD/qquickchangeset_p.h \ $$PWD/qquicklistcompositor_p.h \ $$PWD/qquickpathinterpolator_p.h \ - $$PWD/qquicksvgparser_p.h + $$PWD/qquickimageprovider.h \ + $$PWD/qquicksvgparser_p.h \ + $$PWD/qquickvaluetypes_p.h |