bool QObject::isSignalConnected(const QMetaMethod &signalMetaMethod) const { bool retval = false; const BentoAbstract *signalMethod_Bento = signalMetaMethod.getBentoBox(); std::unique_lock<std::mutex> senderLock{this->m_mutex_ToReceiver}; for(auto index = this->m_connectList_ToReceiver.begin(); index != this->m_connectList_ToReceiver.end(); ++index) { const ConnectStruct &temp = *index; if (*(temp.signalMethod) != *(signalMethod_Bento)) { continue; } if (temp.sender == 0) { // connection is marked for deletion continue; } retval = true; break; } return retval; }
int QObject::receivers(const char *signalMethod) const { int receivers = 0; int index = 0; if (signalMethod) { QByteArray signal_name = QMetaObject::normalizedSignature(signalMethod); const QMetaObject *metaObj = this->metaObject(); index = metaObj->indexOfSignal(signal_name); if (index != -1) { QMetaMethod metaMethod = metaObj->method(index); const BentoAbstract *signalMethod_Bento = metaMethod.getBentoBox(); std::unique_lock<std::mutex> senderLock{this->m_mutex_ToReceiver}; for(auto index = this->m_connectList_ToReceiver.begin(); index != this->m_connectList_ToReceiver.end(); ++index) { const ConnectStruct &temp = *index; if (*(temp.signalMethod) != *(signalMethod_Bento)) { continue; } if (temp.sender == 0) { // connection is marked for deletion continue; } receivers++; } } } // Qt5 if (m_declarativeData && CSAbstractDeclarativeData::receivers) { receivers += CSAbstractDeclarativeData::receivers(m_declarativeData, this, index); } return receivers; }
// used by QAccessibleWidget QList<QObject *> QObject::receiverList(const char *signalMethod) const { QList<QObject *> retval; if (signalMethod) { QByteArray signal_name = QMetaObject::normalizedSignature(signalMethod); const QMetaObject *metaObj = this->metaObject(); int index = metaObj->indexOfSignal(signal_name); if (index == -1) { return retval; } const QMetaMethod signalMetaMethod = metaObj->method(index); const BentoAbstract *signalMethod_Bento = signalMetaMethod.getBentoBox(); std::unique_lock<std::mutex> senderLock{this->m_mutex_ToReceiver}; for(auto k = this->m_connectList_ToReceiver.begin(); k != this->m_connectList_ToReceiver.end(); ++k) { const ConnectStruct &temp = *k; if (! temp.receiver) { continue; } if (*(temp.signalMethod) != *(signalMethod_Bento)) { continue; } if (temp.sender == 0) { // connection is marked for deletion continue; } retval.append(const_cast<QObject *>(temp.receiver)); } } return retval; }
// used by QAccessibleWidget bool QObject::isSender(const QObject *receiver, const char *signalMethod) const { if (signalMethod) { QByteArray signal_name = QMetaObject::normalizedSignature(signalMethod); const QMetaObject *metaObj = this->metaObject(); int index = metaObj->indexOfSignal(signal_name); if (index == -1) { return false; } QMetaMethod metaMethod = metaObj->method(index); const BentoAbstract *signalMethod_Bento = metaMethod.getBentoBox(); std::unique_lock<std::mutex> senderLock{this->m_mutex_ToReceiver}; for(auto k = this->m_connectList_ToReceiver.begin(); k != this->m_connectList_ToReceiver.end(); ++k) { const ConnectStruct &temp = *k; if (temp.sender == 0) { // connection is marked for deletion continue; } if (temp.receiver != receiver) { continue; } if (*(temp.signalMethod) != *(signalMethod_Bento)) { continue; } // found a match return true; } } return false; }
bool QObject::disconnect(const QObject *sender, const QMetaMethod &signalMethod, const QObject *receiver, const QMetaMethod &slotMethod) { const QMetaObject *signalMetaObject = signalMethod.getMetaObject(); const QMetaObject *slotMetaObject = slotMethod.getMetaObject(); // run time checks if (sender == 0) { qWarning("QObject::disconnect() Can not disconnect as sender is null"); return false; } else if (receiver == 0 && slotMetaObject != 0) { qWarning("QObject::disconnect() Can not disconnect as receiver is null and slot was specified"); return false; } if (signalMetaObject) { if (signalMethod.methodType() != QMetaMethod::Signal) { qWarning("QObject::disconnect() Can not disconnect %s::%s, is not a signal", sender->metaObject()->className(), signalMethod.signature()); return false; } } if (slotMetaObject) { if (slotMethod.methodType() == QMetaMethod::Constructor) { qWarning("QObject::disconnect() Can not use constructor as an argument %s::%s", receiver->metaObject()->className(), slotMethod.signature()); return false; } } int signal_index = sender->metaObject()->indexOfSignal(signalMethod.signature()); // if signalMethod is not empty and signal_index is -1, then signal is not a member of sender if (signalMetaObject != 0 && signal_index == -1) { qWarning("QObject::disconnect() Signal %s was not found in class %s", signalMethod.signature(), sender->metaObject()->className()); return false; } // method is not a member of receiver if (receiver) { int slot_index = receiver->metaObject()->indexOfMethod(slotMethod.signature()); if (slotMetaObject && slot_index == -1) { qWarning("QObject::disconnect() Method %s was not found in class %s", slotMethod.signature(), receiver->metaObject()->className()); return false; } } const BentoAbstract *signal_Bento = signalMethod.getBentoBox(); const BentoAbstract *slot_Bento = slotMethod.getBentoBox(); if (! QObject::internal_disconnect(sender, signal_Bento, receiver, slot_Bento)) { return false; } // calling the const char * (Qt4 API version) if (signalMetaObject) { const_cast<QObject*>(sender)->disconnectNotify(signalMethod.signature()); } else { const_cast<QObject*>(sender)->disconnectNotify(0); } return true; }
bool QObject::connect(const QObject *sender, const QMetaMethod &signalMetaMethod, const QObject *receiver, const QMetaMethod &slotMetaMethod, Qt::ConnectionType type) { if (sender == 0) { qWarning("QObject::connect() Can not connect as sender is null"); return false; } if (receiver == 0) { qWarning("QObject::connect() Can not connect as receiver is null"); return false; } // get signal name const char *senderClass = sender->metaObject()->className(); const char *receiverClass = receiver->metaObject()->className(); const char *signalName = signalMetaMethod.signature(); const char *slotName = slotMetaMethod.signature(); if (! signalName || signalName[0] == 0) { qWarning("%s%s%s%s%s", "QObject::connect() ", senderClass, "::<Invalid Signal> ", " Unable to connect to receiver in ", receiverClass); return false; } if (! slotName || slotName[0] == 0 ) { qWarning("%s%s%s%s%s%s%s", "QObject::connect() ", senderClass, "::", signalName, " Unable to connect to receiver in ", receiverClass, "::<Invalid Slot>"); return false; } // is signalMethod a signal if (signalMetaMethod.methodType() != QMetaMethod::Signal) { qWarning("%s%s%s%s%s", "QObject::connect() ", senderClass, "::", signalName, ": Is not a valid signal"); return false; } // is slotMethod a clone, then there is a defualt parameter if (slotMetaMethod.attributes() & QMetaMethod::Cloned) { qWarning("%s%s%s%s%s", "QObject::connect() ", receiverClass, "::", slotName, ": Unable to connect to a slot with a default parameter"); return false; } // test arguments bool err = false; QList<QByteArray> typesSignal = signalMetaMethod.parameterTypes(); QList<QByteArray> typesSlot = slotMetaMethod.parameterTypes(); if (typesSignal.count() < typesSlot.count() ) { err = true; } else { for(int index = 0; index != typesSlot.count(); ++index) { if (typesSignal.at(index) != typesSlot.at(index)) { // unable to test if typeDefs are used err = true; break; } } } if (err) { qWarning("%s%s%s%s%s%s%s%s", "QObject::connect() ", senderClass, "::", signalName, ": Incompatible signal/slot arguments ", receiverClass, "::", slotName); return false; } // if (type == Qt::AutoCompatConnection) { type = Qt::AutoConnection; } // const BentoAbstract *signalMethod_Bento = signalMetaMethod.getBentoBox(); const BentoAbstract *slotMethod_Bento = slotMetaMethod.getBentoBox(); if (! signalMethod_Bento) { qWarning("%s%s%s%s%s", "QObject::connect() ", senderClass, "::", signalName, " Unable to locate the requested signal, verify connect arguments and signal declaration"); return false; } if (! slotMethod_Bento) { qWarning("%s%s%s%s%s", "QObject::connect() ", receiverClass, "::", slotName, " Unable to locate the requested slot, verify connect arguments and slot declaration"); return false; } std::unique_lock<std::mutex> senderLock{sender->m_mutex_ToReceiver}; std::unique_lock<std::mutex> receiverLock{receiver->m_mutex_FromSender}; if (type & Qt::UniqueConnection) { // user passed enum to ensure the connection is not added twice for(auto index = sender->m_connectList_ToReceiver.begin(); index != sender->m_connectList_ToReceiver.end(); ++index) { const ConnectStruct &temp = *index; if (temp.sender == 0) { // connection is marked for deletion continue; } if (temp.receiver != receiver) { continue; } if (*(temp.signalMethod) != *(signalMethod_Bento)) { continue; } if (*(temp.slotMethod) != *(slotMethod_Bento)) { continue; } // connection already exists return false; } // change type type = static_cast<Qt::ConnectionType>(type & ~Qt::UniqueConnection); } sender->addConnection(signalMethod_Bento, receiver, slotMethod_Bento, type); sender->connectNotify(signalMetaMethod); return true; }