summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2011-11-25 22:35:32 +0100
committerQt by Nokia <qt-info@nokia.com>2011-11-29 17:11:59 +0100
commit0dec6250f7538c79c4698c3952a46105bc264e4e (patch)
treeea7dc9079fd990346fb1dd0e3e4a6cf87fc8a514 /src
parent8350d91245ff122d03c628ea297a808d86103cd1 (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')
-rw-r--r--src/corelib/kernel/qobject.cpp54
-rw-r--r--src/corelib/kernel/qobject.h18
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);