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}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\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 *))
|
||||
\relates QQmlEngine
|
||||
|
|
|
@ -149,6 +149,25 @@ QObject *qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc
|
|||
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,
|
||||
const char *uri, int versionMajor,
|
||||
int versionMinor, const char *qmlName,
|
||||
|
|
|
@ -615,6 +615,7 @@ Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *,
|
|||
const QMetaObject *);
|
||||
Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func,
|
||||
bool create = true);
|
||||
Q_QML_EXPORT QObject *qmlExtendedObject(QObject *);
|
||||
|
||||
//The C++ version of protected namespaces in qmldir
|
||||
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);
|
||||
|
||||
if ((c == QMetaObject::ReadProperty ||
|
||||
c == QMetaObject::WriteProperty) &&
|
||||
id >= metaObjects->constLast().propertyOffset) {
|
||||
switch (c) {
|
||||
case QMetaObject::ReadProperty:
|
||||
case QMetaObject::WriteProperty: {
|
||||
if (id < metaObjects->constLast().propertyOffset)
|
||||
break;
|
||||
|
||||
for (int ii = 0; ii < metaObjects->count(); ++ii) {
|
||||
const int globalPropertyOffset = metaObjects->at(ii).propertyOffset;
|
||||
if (id >= globalPropertyOffset) {
|
||||
QObject *proxy = getProxy(ii);
|
||||
const int localProxyOffset = proxy->metaObject()->propertyOffset();
|
||||
const int localProxyId = id - globalPropertyOffset + localProxyOffset;
|
||||
if (id < globalPropertyOffset)
|
||||
continue;
|
||||
|
||||
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 &&
|
||||
id >= metaObjects->constLast().methodOffset) {
|
||||
break;
|
||||
}
|
||||
case QMetaObject::InvokeMetaMethod: {
|
||||
if (id < metaObjects->constLast().methodOffset)
|
||||
break;
|
||||
|
||||
QMetaMethod m = object->metaObject()->method(id);
|
||||
if (m.methodType() == QMetaMethod::Signal) {
|
||||
QMetaObject::activate(object, id, a);
|
||||
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)
|
||||
|
|
|
@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE
|
|||
class QQmlProxyMetaObject : public QDynamicMetaObjectData
|
||||
{
|
||||
public:
|
||||
enum { ExtensionObjectId = std::numeric_limits<int>::min() };
|
||||
|
||||
struct ProxyData {
|
||||
typedef QObject *(*CreateFunc)(QObject *);
|
||||
QMetaObject *metaObject;
|
||||
|
|
|
@ -5657,6 +5657,10 @@ void tst_qqmllanguage::extendedForeignTypes()
|
|||
QCOMPARE(o->property("foreignExtendedObjectName").toString(), QLatin1String("foreignExtended"));
|
||||
QCOMPARE(o->property("extendedInvokable").toInt(), 123);
|
||||
QCOMPARE(o->property("extendedSlot").toInt(), 456);
|
||||
|
||||
QObject *extension = qmlExtendedObject(extended);
|
||||
QVERIFY(extension != nullptr);
|
||||
QVERIFY(qobject_cast<Extension *>(extension) != nullptr);
|
||||
}
|
||||
|
||||
void tst_qqmllanguage::foreignTypeSingletons() {
|
||||
|
|
Loading…
Reference in New Issue