QMetaMethod QpMetaObject::method(QString signature, const QpMetaProperty &property) const { QString propertyName = property.name(); propertyName[0] = propertyName.at(0).toTitleCase(); QString reverseClassName = property.reverseClassName(); QMetaMethod method = findMethod(signature.arg(propertyName).arg(reverseClassName)); if (method.isValid()) return method; QString reverseClassNameWithoutNamespaces = removeNamespaces(reverseClassName); if (reverseClassNameWithoutNamespaces == reverseClassName) return QMetaMethod(); method = findMethod(signature.arg(propertyName).arg(reverseClassNameWithoutNamespaces)); if (method.isValid()) return method; Q_ASSERT_X(false, Q_FUNC_INFO, QString("No such method '%1::%2'") .arg(data->metaObject.className()) .arg(signature.arg(propertyName).arg(reverseClassName)).toLatin1()); return QMetaMethod(); }
void ActionExecutor::Object::disconnectSignals(const QObject *receiver, const QMetaMethod *actionsStateChangedMethod, const QMetaMethod *arbitraryActionsStateChangedMethod, const QMetaMethod *categorizedActionsStateChangedMethod) { if (receiver && m_object) { const QMetaObject *metaObject(m_object.data()->metaObject()); const QMetaMethod actionsStateChangedSignal(metaObject->method(metaObject->indexOfSignal("actionsStateChanged()"))); const QMetaMethod arbitraryActionsStateChangedSignal(metaObject->method(metaObject->indexOfSignal("arbitraryActionsStateChanged(QVector<int>)"))); const QMetaMethod categorizedActionsStateChangedSignal(metaObject->method(metaObject->indexOfSignal("categorizedActionsStateChanged(QVector<int>)"))); if (actionsStateChangedSignal.isValid() && actionsStateChangedMethod) { QObject::disconnect(m_object.data(), actionsStateChangedSignal, receiver, *(actionsStateChangedMethod)); } if (arbitraryActionsStateChangedSignal.isValid() && arbitraryActionsStateChangedMethod) { QObject::disconnect(m_object.data(), arbitraryActionsStateChangedSignal, receiver, *(arbitraryActionsStateChangedMethod)); } if (categorizedActionsStateChangedSignal.isValid() && categorizedActionsStateChangedMethod) { QObject::disconnect(m_object.data(), categorizedActionsStateChangedSignal, receiver, *(categorizedActionsStateChangedMethod)); } } }
/*! \internal Catch signal disconnections. */ void QDBusAbstractInterface::disconnectNotify(const QMetaMethod &signal) { // someone disconnecting from one of our signals Q_D(QDBusAbstractInterface); if (!d->isValid) return; QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn && signal.isValid() && !isSignalConnected(signal)) return conn->disconnectRelay(d->service, d->path, d->interface, this, signal); if (!conn) return; // wildcard disconnecting, we need to figure out which of our signals are // no longer connected to anything const QMetaObject *mo = metaObject(); int midx = QObject::staticMetaObject.methodCount(); const int end = mo->methodCount(); for ( ; midx < end; ++midx) { QMetaMethod mm = mo->method(midx); if (mm.methodType() == QMetaMethod::Signal && !isSignalConnected(mm)) conn->disconnectRelay(d->service, d->path, d->interface, this, mm); } }
int Test::qt_metacall(QMetaObject::Call call, int id, void **args) { id = QObject::qt_metacall(call, id, args); if (id < 0 || !d->meta) return id; if (call == QMetaObject::InvokeMetaMethod) { int metaIndex = id + d->meta->methodOffset(); QMetaMethod method = d->meta->method(metaIndex); if (!method.isValid()) { qWarning() << "invoked invalid method with id" << id; return -1; } QVariantList vargs; for (int i = 0; i < method.parameterCount(); ++i) vargs.append(QVariant(method.parameterType(i), args[1 + i])); QString catchedName = d->slotId2Name.value(metaIndex); void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&catchedName)), const_cast<void*>(reinterpret_cast<const void*>(&vargs)) }; QMetaObject::activate(this, metaObject(), d->catchedSignalId, _a); } return -1; }
void DataWidgetMapper::addMapping(QWidget *widget, int section) { QMetaProperty property = widget->metaObject()->userProperty(); Q_ASSERT(property.isValid()); QMetaMethod notifySignal = property.notifySignal(); Q_ASSERT(notifySignal.isValid()); connect(widget, notifySignal, this, QMetaMethod::fromSignal(&DataWidgetMapper::dataChanged)); QDataWidgetMapper::addMapping(widget, section); }
void Bindable::bind(const QString &id, const QObject *receiver, const char *methodSignature) { auto mo = receiver->metaObject(); Q_ASSERT_X(mo, "Bindable::bind", "Invalid metaobject. Did you forget the QObject macro?"); const QMetaMethod method = mo->method( mo->indexOfMethod(QMetaObject::normalizedSignature(methodSignature + 1).constData())); Q_ASSERT_X(method.isValid(), "Bindable::bind", "Invalid method signature"); m_bindings.insert(id, Detail::Binding(receiver, method)); }
void tst_QMetaMethod::invalidMethod() { QMetaMethod method; QVERIFY(!method.isValid()); QMetaMethod method2 = staticMetaObject.method(staticMetaObject.methodCount()); QVERIFY(!method2.isValid()); QMetaMethod method3 = staticMetaObject.method(-1); QVERIFY(!method3.isValid()); }
/*! \internal Returns the signal that corresponds to \a proxySignal in the meta-object of the \a sourceObject. */ static QMetaMethod proxyToSourceSignal(const QMetaMethod &proxySignal, QObject *sourceObject) { if (!proxySignal.isValid()) return proxySignal; Q_ASSERT(proxySignal.methodType() == QMetaMethod::Signal); Q_ASSERT(sourceObject != 0); const QMetaObject *sourceMeta = sourceObject->metaObject(); int sourceIndex = sourceMeta->indexOfSignal(proxySignal.methodSignature()); Q_ASSERT(sourceIndex != -1); return sourceMeta->method(sourceIndex); }
/*! \reimp \internal */ void QBuffer::disconnectNotify(const QMetaMethod &signal) { if (signal.isValid()) { static const QMetaMethod readyReadSignal = QMetaMethod::fromSignal(&QBuffer::readyRead); static const QMetaMethod bytesWrittenSignal = QMetaMethod::fromSignal(&QBuffer::bytesWritten); if (signal == readyReadSignal || signal == bytesWrittenSignal) d_func()->signalConnectionCount--; } else { d_func()->signalConnectionCount = 0; } }
bool PacketReceiver::registerListener(PacketType type, QObject* listener, const char* slot, bool deliverPending) { Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No object to register"); Q_ASSERT_X(slot, "PacketReceiver::registerListener", "No slot to register"); QMetaMethod matchingMethod = matchingMethodForListener(type, listener, slot); if (matchingMethod.isValid()) { qCDebug(networking) << "Registering a packet listener for packet list type" << type; registerVerifiedListener(type, listener, matchingMethod, deliverPending); return true; } else { qCWarning(networking) << "FAILED to Register a packet listener for packet list type" << type; return false; } }
void tst_QMetaMethod::method() { QFETCH(QByteArray, signature); QFETCH(int, returnType); QFETCH(QByteArray, returnTypeName); QFETCH(QList<int>, parameterTypes); QFETCH(QList<QByteArray>, parameterTypeNames); QFETCH(QList<QByteArray>, parameterNames); QFETCH(QMetaMethod::MethodType, methodType); QFETCH(QMetaMethod::Access, access); QVERIFY(parameterTypes.size() == parameterTypeNames.size()); QVERIFY(parameterTypes.size() == parameterNames.size()); const QMetaObject *mo = &MethodTestObject::staticMetaObject; int index = (methodType == QMetaMethod::Constructor) ? mo->indexOfConstructor(signature) : mo->indexOfMethod(signature); QVERIFY(index != -1); QMetaMethod method = (methodType == QMetaMethod::Constructor) ? mo->constructor(index) : mo->method(index); QVERIFY(method.isValid()); QCOMPARE(method.methodType(), methodType); QCOMPARE(method.access(), access); QVERIFY(!method.methodSignature().isEmpty()); if (method.methodSignature() != signature) { // QMetaMethod should always produce a semantically equivalent signature int signatureIndex = (methodType == QMetaMethod::Constructor) ? mo->indexOfConstructor(method.methodSignature()) : mo->indexOfMethod(method.methodSignature()); QCOMPARE(signatureIndex, index); } QByteArray computedName = signature.left(signature.indexOf('(')); QCOMPARE(method.name(), computedName); QCOMPARE(method.tag(), ""); QCOMPARE(method.returnType(), returnType); QVERIFY(method.typeName() != 0); if (QByteArray(method.typeName()) != returnTypeName) { // QMetaMethod should always produce a semantically equivalent typename QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName)); } if (method.parameterTypes() != parameterTypeNames) { // QMetaMethod should always produce semantically equivalent typenames QList<QByteArray> actualTypeNames = method.parameterTypes(); QCOMPARE(actualTypeNames.size(), parameterTypeNames.size()); for (int i = 0; i < parameterTypeNames.size(); ++i) { QCOMPARE(QMetaType::type(actualTypeNames.at(i)), QMetaType::type(parameterTypeNames.at(i))); } } QCOMPARE(method.parameterNames(), parameterNames); QCOMPARE(method.parameterCount(), parameterTypes.size()); for (int i = 0; i < parameterTypes.size(); ++i) QCOMPARE(method.parameterType(i), parameterTypes.at(i)); { QVector<int> actualParameterTypes(parameterTypes.size()); method.getParameterTypes(actualParameterTypes.data()); for (int i = 0; i < parameterTypes.size(); ++i) QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i)); } // Bogus indexes QCOMPARE(method.parameterType(-1), 0); QCOMPARE(method.parameterType(parameterTypes.size()), 0); }
void QDBusViewer::callMethod(const BusSignature &sig) { QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c); const QMetaObject *mo = iface.metaObject(); // find the method QMetaMethod method; for (int i = 0; i < mo->methodCount(); ++i) { const QString signature = QString::fromLatin1(mo->method(i).methodSignature()); if (signature.startsWith(sig.mName) && signature.at(sig.mName.length()) == QLatin1Char('(')) if (getDbusSignature(mo->method(i)) == sig.mTypeSig) method = mo->method(i); } if (!method.isValid()) { QMessageBox::warning(this, tr("Unable to find method"), tr("Unable to find method %1 on path %2 in interface %3").arg( sig.mName).arg(sig.mPath).arg(sig.mInterface)); return; } PropertyDialog dialog; QList<QVariant> args; const QList<QByteArray> paramTypes = method.parameterTypes(); const QList<QByteArray> paramNames = method.parameterNames(); QList<int> types; // remember the low-level D-Bus type for (int i = 0; i < paramTypes.count(); ++i) { const QByteArray paramType = paramTypes.at(i); if (paramType.endsWith('&')) continue; // ignore OUT parameters int type = QMetaType::type(paramType); dialog.addProperty(QString::fromLatin1(paramNames.value(i)), type); types.append(type); } if (!types.isEmpty()) { dialog.setInfo(tr("Please enter parameters for the method \"%1\"").arg(sig.mName)); if (dialog.exec() != QDialog::Accepted) return; args = dialog.values(); } // Try to convert the values we got as closely as possible to the // dbus signature. This is especially important for those input as strings for (int i = 0; i < args.count(); ++i) { QVariant a = args.at(i); int desttype = types.at(i); if (desttype < int(QMetaType::User) && desttype != int(QVariant::Map) && a.canConvert(desttype)) { args[i].convert(desttype); } // Special case - convert a value to a QDBusVariant if the // interface wants a variant if (types.at(i) == qMetaTypeId<QDBusVariant>()) args[i] = QVariant::fromValue(QDBusVariant(args.at(i))); } QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, sig.mInterface, sig.mName); message.setArguments(args); c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage))); }
void ensureInitialized() { if (!onVisibleChanged.isValid()) { int index = q_ptr->metaObject()->indexOfMethod("implementationVisibileChanged()"); Q_ASSERT(index >= 0); onVisibleChanged = q_ptr->metaObject()->method(index); } if (component.isNull()) { Config config; config.beginGroup(QStringLiteral("qml/themes")); QString themeName = config.value(dialogName, QStringLiteral("default")); QString themePath = ThemeManager::path(QStringLiteral("qml/") + dialogName, themeName); if (themePath.isEmpty()) { qWarning() << "Failed to find theme:" << themeName << "for dialog:" << dialogName; themePath = ThemeManager::path(QStringLiteral("qml/") + dialogName, QStringLiteral("default")); if (themePath.isEmpty()) { qCritical() << "Failed to find default theme for dialog:" << dialogName; return; } } QString fileName = themePath + QStringLiteral("/main.qml"); component.reset(new QQmlComponent(DeclarativeView::globalEngine(), fileName)); } if (dialog.isNull()) { dialog = component->create(); visibleProperty = QMetaProperty(); if (!dialog) { qCritical() << "Failed to create object for component:" << component->url() << "errors:"; for (QQmlError error : component->errors()) { qCritical() << error.toString(); } return; } deathConnection = QObject::connect(dialog.data(), &QObject::destroyed, q_ptr, [this] () { dialog.clear(); visibleProperty = QMetaProperty(); updateVisible(); }); int visibleIndex = dialog->metaObject()->indexOfProperty("visible"); if (visibleIndex < 0) { qCritical() << "Failed to find \"visible\" property for component:" << component->url(); return; } visibleProperty = dialog->metaObject()->property(visibleIndex); if (!visibleProperty.hasNotifySignal()) { qCritical() << "Property \"visible\" has no notify signal for component:" << component->url(); } else { QObject::connect(dialog.data(), visibleProperty.notifySignal(), q_ptr, onVisibleChanged); } updateVisible(); } }
void DataWidgetMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) { QMetaProperty property; for (int i=0; i<widget->metaObject()->propertyCount(); ++i) { if (QString(widget->metaObject()->property(i).name()) == propertyName) { property = widget->metaObject()->property(i); break; } } Q_ASSERT(property.isValid()); QMetaMethod notifySignal = property.notifySignal(); Q_ASSERT(notifySignal.isValid()); connect(widget, notifySignal, this, QMetaMethod::fromSignal(&DataWidgetMapper::dataChanged)); QDataWidgetMapper::addMapping(widget, section, propertyName); }