diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2011-11-25 22:35:32 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-29 17:11:59 +0100 |
commit | 0dec6250f7538c79c4698c3952a46105bc264e4e (patch) | |
tree | ea7dc9079fd990346fb1dd0e3e4a6cf87fc8a514 /src/corelib | |
parent | 8350d91245ff122d03c628ea297a808d86103cd1 (diff) |
Support Qt::UniqueConnection in the new connection syntax
This commit also improves the related documentation a bit.
The test is copied from the test with the old syntax, but all the
connection statement are changed to use the new syntax
Change-Id: Ia5630ca4335b9f8ca6d724ae3c8750d6f0804d8e
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 54 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.h | 18 |
2 files changed, 59 insertions, 13 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 5b50f0ebff..b1d2463737 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2366,7 +2366,7 @@ static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaM If you pass the Qt::UniqueConnection \a type, the connection will only be made if it is not a duplicate. If there is already a duplicate (exact same signal to the exact same slot on the same objects), - the connection will fail and connect will return false. + the connection will fail and connect will return an invalid QMetaObject::Connection. The optional \a type parameter describes the type of connection to establish. In particular, it determines whether a particular @@ -4089,6 +4089,14 @@ void qDeleteInEventHandler(QObject *o) to verify the existence of \a signal (if it was not declared as a signal) You can check if the QMetaObject::Connection is valid by casting it to a bool. + By default, a signal is emitted for every connection you make; + two signals are emitted for duplicate connections. You can break + all of these connections with a single disconnect() call. + If you pass the Qt::UniqueConnection \a type, the connection will only + be made if it is not a duplicate. If there is already a duplicate + (exact same signal to the exact same slot on the same objects), + the connection will fail and connect will return an invalid QMetaObject::Connection. + The optional \a type parameter describes the type of connection to establish. In particular, it determines whether a particular signal is delivered to a slot immediately or queued for delivery @@ -4136,9 +4144,35 @@ void qDeleteInEventHandler(QObject *o) The connection will automatically disconnect if the sender is destroyed. */ -QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal, const QObject *receiver, QObject::QSlotObjectBase *slotObj, - Qt::ConnectionType type, const int* types, const QMetaObject* senderMetaObject) + +/** \internal + + Implementation of the template version of connect + + \a sender is the sender object + \a signal is a pointer to a pointer to a member signal of the sender + \a receiver is the receiver object, may not be null, will be equal to sender when + connecting to a static function or a functor + \a slot a pointer only used when using Qt::UniqueConnection + \a type the Qt::ConnctionType passed as argument to connect + \a types an array of integer with the metatype id of the parametter of the signal + to be used with queued connection + must stay valid at least for the whole time of the connection, this function + do not take ownership. typically static data. + If null, then the types will be computed when the signal is emit in a queued + connection from the types from the signature. + \a senderMetaObject is the metaobject used to lookup the signal, the signal must be in + this metaobject + */ +QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal, + const QObject *receiver, void **slot, + QObject::QSlotObjectBase *slotObj, Qt::ConnectionType type, + const int *types, const QMetaObject *senderMetaObject) { + if (!sender || !signal || !slotObj || !senderMetaObject) { + qWarning("QObject::connect: invalid null parametter"); + return QMetaObject::Connection(); + } int signal_index = -1; void *args[] = { &signal_index, signal }; senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args); @@ -4157,8 +4191,18 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa signalSlotLock(receiver)); if (type & Qt::UniqueConnection) { - qWarning() << "QObject::connect: Qt::UniqueConnection not supported when connecting function pointers"; - type = static_cast<Qt::ConnectionType>(type & (Qt::UniqueConnection - 1)); + QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists; + if (connectionLists && connectionLists->count() > signal_index) { + const QObjectPrivate::Connection *c2 = + (*connectionLists)[signal_index].first; + + while (c2) { + if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) + return QMetaObject::Connection(); + c2 = c2->nextConnectionList; + } + } + type = static_cast<Qt::ConnectionType>(type ^ Qt::UniqueConnection); } QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection); diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 3b8803c1a6..48c0bdbfcb 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -225,9 +225,9 @@ public: types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types(); return connectImpl(sender, reinterpret_cast<void **>(&signal), - receiver, new QSlotObject<Func2, - typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value, - typename SignalType::ReturnType>(slot), + receiver, reinterpret_cast<void **>(&slot), + new QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value, + typename SignalType::ReturnType>(slot), type, types, &SignalType::Object::staticMetaObject); } @@ -243,7 +243,7 @@ public: typedef typename QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::IncompatibleSignalSlotArguments EnsureCompatibleArguments; typedef typename QtPrivate::QEnableIf<(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount))>::Type EnsureArgumentsCount; - return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, + return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0, new QStaticSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value, typename SignalType::ReturnType>(slot), @@ -257,8 +257,8 @@ public: { typedef QtPrivate::FunctionPointer<Func1> SignalType; - return connectImpl(sender, reinterpret_cast<void **>(&signal), - sender, new QFunctorSlotObject<Func2, SignalType::ArgumentCount, typename SignalType::Arguments, typename SignalType::ReturnType>(slot), + return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0, + new QFunctorSlotObject<Func2, SignalType::ArgumentCount, typename SignalType::Arguments, typename SignalType::ReturnType>(slot), Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject); } @@ -407,8 +407,10 @@ private: } }; - static QMetaObject::Connection connectImpl(const QObject *sender, void **signal, const QObject *receiver, QSlotObjectBase *slot, - Qt::ConnectionType type, const int *types, const QMetaObject *senderMetaObject); + static QMetaObject::Connection connectImpl(const QObject *sender, void **signal, + const QObject *receiver, void **slotPtr, + QSlotObjectBase *slot, Qt::ConnectionType type, + const int *types, const QMetaObject *senderMetaObject); static bool disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot, const QMetaObject *senderMetaObject); |