static bool NPClass_HasProperty(NPObject *npobj, NPIdentifier name) { NPClass_Prolog; const QByteArray qname = NPN_UTF8FromIdentifier(name); const QMetaObject *metaObject = qobject->metaObject(); int propertyIndex = metaObject->indexOfProperty(qname); if (propertyIndex == -1 || propertyIndex < metaOffset(metaObject, MetaProperty)) return false; QMetaProperty property = qobject->metaObject()->property(propertyIndex); if (!property.isScriptable()) return false; return true; }
static int publicMethodIndex(NPObject *npobj, NPIdentifier name) { NPClass_Prolog; QByteArray qname = NPN_UTF8FromIdentifier(name); const QMetaObject *metaObject = qobject->metaObject(); for (int slotIndex = metaOffset(metaObject, MetaMethod); slotIndex < metaObject->methodCount(); ++slotIndex) { const QMetaMethod slot = qobject->metaObject()->method(slotIndex); if (slot.access() != QMetaMethod::Public || slot.methodType() == QMetaMethod::Signal) continue; QByteArray signature = slot.signature(); if (signature.left(signature.indexOf('(')) == qname) return slotIndex; } return -1; }
static int publicMethodIndex(NPObject *npobj, const QByteArray &slotName, int argCount = -1) { NPClass_Prolog; const QMetaObject *metaObject = qobject->metaObject(); for (int slotIndex = metaOffset(metaObject, MetaMethod); slotIndex < metaObject->methodCount(); ++slotIndex) { const QMetaMethod slot = qobject->metaObject()->method(slotIndex); if (slot.access() != QMetaMethod::Public || slot.methodType() == QMetaMethod::Signal) continue; QByteArray signature = slot.signature(); if (signature.left(signature.indexOf('(')) == slotName) { if (argCount == -1 || slot.parameterTypes().count() == argCount) return slotIndex; } } return -1; }
int QtSignalForwarder::qt_metacall(QMetaObject::Call call, int index, void **args) { // no support for QObject method/properties etc! if (!This || !This->npp || call != QMetaObject::InvokeMetaMethod || !This->qt.object) return index; switch (index) { case -1: { QString msg = *(QString*)args[1]; NPN_Status(This->npp, msg.toLocal8Bit().constData()); } break; default: { QObject *qobject = This->qt.object; if (!domNode) NPN_GetValue(This->npp, NPNVPluginElementNPObject, &domNode); if (!domNode) break; const QMetaObject *metaObject = qobject->metaObject(); if (index < metaOffset(metaObject, MetaMethod)) break; const QMetaMethod method = metaObject->method(index); Q_ASSERT(method.methodType() == QMetaMethod::Signal); QByteArray signalSignature = method.signature(); QByteArray scriptFunction = signalSignature.left(signalSignature.indexOf('(')); NPIdentifier id = NPN_GetStringIdentifier(scriptFunction.constData()); if (NPN_HasMethod(This->npp, domNode, id)) { QList<QByteArray> parameterTypes = method.parameterTypes(); QVector<NPVariant> parameters; NPVariant result; bool error = false; for (int p = 0; p < parameterTypes.count(); ++p) { QVariant::Type type = QVariant::nameToType(parameterTypes.at(p)); if (type == QVariant::Invalid) { NPN_SetException(domNode, QByteArray("Unsupported parameter type in ") + scriptFunction); error = true; break; } QVariant qvar(type, args[p + 1]); NPVariant npvar = NPVariant::fromQVariant(This, qvar); if (npvar.type == NPVariant::Null || npvar.type == NPVariant::Void) { NPN_SetException(domNode, QByteArray("Unsupported parameter value in ") + scriptFunction); error =true; break; } parameters += npvar; } if (error) break; NPError nperror = NPN_Invoke(This->npp, domNode, id, parameters.constData(), parameters.count(), &result); if (nperror != NPERR_NO_ERROR && false) { // disabled, as NPN_Invoke seems to always return GENERICERROR NPN_SetException(domNode, QByteArray("Error invoking event handler ") + scriptFunction); } // ### TODO: update return value (args[0]) (out-parameters not supported anyway) NPN_ReleaseVariantValue(&result); } } break; } return index; }