Add public API for retrieving the extension object
Change-Id: I28bc1c177cb78d85d844c7a5cd5b6710db8fd65d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
00b59c391e
commit
cc6bd22b61
|
@ -991,6 +991,16 @@
|
||||||
\sa QML_ATTACHED(), {Providing Attached Properties}
|
\sa QML_ATTACHED(), {Providing Attached Properties}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QObject *qmlExtendedObject(const QObject *base)
|
||||||
|
\relates QQmlEngine
|
||||||
|
|
||||||
|
This function returns the extension object that belongs to \a base, if there is any.
|
||||||
|
Otherwise it returns \c nullptr.
|
||||||
|
|
||||||
|
\sa QML_EXTENDED
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*callback)(QQmlEngine *, QJSEngine *))
|
\fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*callback)(QQmlEngine *, QJSEngine *))
|
||||||
\relates QQmlEngine
|
\relates QQmlEngine
|
||||||
|
|
|
@ -149,6 +149,25 @@ QObject *qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc
|
||||||
return resolveAttachedProperties(func, data, object, create);
|
return resolveAttachedProperties(func, data, object, create);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QObject *qmlExtendedObject(QObject *object)
|
||||||
|
{
|
||||||
|
if (!object)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
void *result = nullptr;
|
||||||
|
QObjectPrivate *d = QObjectPrivate::get(object);
|
||||||
|
if (!d->metaObject)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const int id = d->metaObject->metaCall(
|
||||||
|
object, QMetaObject::CustomCall,
|
||||||
|
QQmlProxyMetaObject::ExtensionObjectId, &result);
|
||||||
|
if (id != QQmlProxyMetaObject::ExtensionObjectId)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return static_cast<QObject *>(result);
|
||||||
|
}
|
||||||
|
|
||||||
int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
|
int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
|
||||||
const char *uri, int versionMajor,
|
const char *uri, int versionMajor,
|
||||||
int versionMinor, const char *qmlName,
|
int versionMinor, const char *qmlName,
|
||||||
|
|
|
@ -615,6 +615,7 @@ Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *,
|
||||||
const QMetaObject *);
|
const QMetaObject *);
|
||||||
Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func,
|
Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func,
|
||||||
bool create = true);
|
bool create = true);
|
||||||
|
Q_QML_EXPORT QObject *qmlExtendedObject(QObject *);
|
||||||
|
|
||||||
//The C++ version of protected namespaces in qmldir
|
//The C++ version of protected namespaces in qmldir
|
||||||
Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion);
|
Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion);
|
||||||
|
|
|
@ -104,39 +104,54 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
|
||||||
{
|
{
|
||||||
Q_ASSERT(object == o);
|
Q_ASSERT(object == o);
|
||||||
|
|
||||||
if ((c == QMetaObject::ReadProperty ||
|
switch (c) {
|
||||||
c == QMetaObject::WriteProperty) &&
|
case QMetaObject::ReadProperty:
|
||||||
id >= metaObjects->constLast().propertyOffset) {
|
case QMetaObject::WriteProperty: {
|
||||||
|
if (id < metaObjects->constLast().propertyOffset)
|
||||||
|
break;
|
||||||
|
|
||||||
for (int ii = 0; ii < metaObjects->count(); ++ii) {
|
for (int ii = 0; ii < metaObjects->count(); ++ii) {
|
||||||
const int globalPropertyOffset = metaObjects->at(ii).propertyOffset;
|
const int globalPropertyOffset = metaObjects->at(ii).propertyOffset;
|
||||||
if (id >= globalPropertyOffset) {
|
if (id < globalPropertyOffset)
|
||||||
QObject *proxy = getProxy(ii);
|
continue;
|
||||||
const int localProxyOffset = proxy->metaObject()->propertyOffset();
|
|
||||||
const int localProxyId = id - globalPropertyOffset + localProxyOffset;
|
|
||||||
|
|
||||||
return proxy->qt_metacall(c, localProxyId, a);
|
QObject *proxy = getProxy(ii);
|
||||||
}
|
const int localProxyOffset = proxy->metaObject()->propertyOffset();
|
||||||
|
const int localProxyId = id - globalPropertyOffset + localProxyOffset;
|
||||||
|
return proxy->qt_metacall(c, localProxyId, a);
|
||||||
}
|
}
|
||||||
} else if (c == QMetaObject::InvokeMetaMethod &&
|
break;
|
||||||
id >= metaObjects->constLast().methodOffset) {
|
}
|
||||||
|
case QMetaObject::InvokeMetaMethod: {
|
||||||
|
if (id < metaObjects->constLast().methodOffset)
|
||||||
|
break;
|
||||||
|
|
||||||
QMetaMethod m = object->metaObject()->method(id);
|
QMetaMethod m = object->metaObject()->method(id);
|
||||||
if (m.methodType() == QMetaMethod::Signal) {
|
if (m.methodType() == QMetaMethod::Signal) {
|
||||||
QMetaObject::activate(object, id, a);
|
QMetaObject::activate(object, id, a);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
for (int ii = 0; ii < metaObjects->count(); ++ii) {
|
|
||||||
const int globalMethodOffset = metaObjects->at(ii).methodOffset;
|
|
||||||
if (id >= globalMethodOffset) {
|
|
||||||
QObject *proxy = getProxy(ii);
|
|
||||||
|
|
||||||
const int localMethodOffset = proxy->metaObject()->methodOffset();
|
|
||||||
const int localMethodId = id - globalMethodOffset + localMethodOffset;
|
|
||||||
|
|
||||||
return proxy->qt_metacall(c, localMethodId, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int ii = 0; ii < metaObjects->count(); ++ii) {
|
||||||
|
const int globalMethodOffset = metaObjects->at(ii).methodOffset;
|
||||||
|
if (id < globalMethodOffset)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QObject *proxy = getProxy(ii);
|
||||||
|
const int localMethodOffset = proxy->metaObject()->methodOffset();
|
||||||
|
const int localMethodId = id - globalMethodOffset + localMethodOffset;
|
||||||
|
return proxy->qt_metacall(c, localMethodId, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QMetaObject::CustomCall:
|
||||||
|
if (id != ExtensionObjectId)
|
||||||
|
break;
|
||||||
|
a[0] = getProxy(0);
|
||||||
|
return id;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
|
|
|
@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE
|
||||||
class QQmlProxyMetaObject : public QDynamicMetaObjectData
|
class QQmlProxyMetaObject : public QDynamicMetaObjectData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum { ExtensionObjectId = std::numeric_limits<int>::min() };
|
||||||
|
|
||||||
struct ProxyData {
|
struct ProxyData {
|
||||||
typedef QObject *(*CreateFunc)(QObject *);
|
typedef QObject *(*CreateFunc)(QObject *);
|
||||||
QMetaObject *metaObject;
|
QMetaObject *metaObject;
|
||||||
|
|
|
@ -5657,6 +5657,10 @@ void tst_qqmllanguage::extendedForeignTypes()
|
||||||
QCOMPARE(o->property("foreignExtendedObjectName").toString(), QLatin1String("foreignExtended"));
|
QCOMPARE(o->property("foreignExtendedObjectName").toString(), QLatin1String("foreignExtended"));
|
||||||
QCOMPARE(o->property("extendedInvokable").toInt(), 123);
|
QCOMPARE(o->property("extendedInvokable").toInt(), 123);
|
||||||
QCOMPARE(o->property("extendedSlot").toInt(), 456);
|
QCOMPARE(o->property("extendedSlot").toInt(), 456);
|
||||||
|
|
||||||
|
QObject *extension = qmlExtendedObject(extended);
|
||||||
|
QVERIFY(extension != nullptr);
|
||||||
|
QVERIFY(qobject_cast<Extension *>(extension) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_qqmllanguage::foreignTypeSingletons() {
|
void tst_qqmllanguage::foreignTypeSingletons() {
|
||||||
|
|
Loading…
Reference in New Issue