summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-05-25 20:47:06 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-05-27 08:30:53 (GMT)
commit0ea19cf01e2381969a8b8ce8cdaffe9ce873d3a9 (patch)
tree366d238fbd75b808de8aa7b701351f225a7e79dc /src/corelib/kernel
parent5e14efa547ffac5890b008ad23e9ff0bc634a3e1 (diff)
downloadQt-0ea19cf01e2381969a8b8ce8cdaffe9ce873d3a9.zip
Qt-0ea19cf01e2381969a8b8ce8cdaffe9ce873d3a9.tar.gz
Qt-0ea19cf01e2381969a8b8ce8cdaffe9ce873d3a9.tar.bz2
Add a flag that ensure that a connection is made only one
It is often desirable, when doing connection, to ensure that the same connection is only made once. This can be done with the Qt::UniqueConnection 'flag' Also documented the order the slot are called Reviewed-by: Brad
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qobject.cpp36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 65d81f1..be622d9 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -301,7 +301,6 @@ void QObjectPrivate::addConnection(int signal, Connection *c)
ConnectionList &connectionList = (*connectionLists)[signal];
connectionList.append(c);
-
cleanConnectionLists();
}
@@ -2377,7 +2376,8 @@ int QObject::receivers(const char *signal) const
can be connected to one slot.
If a signal is connected to several slots, the slots are activated
- in an arbitrary order when the signal is emitted.
+ in the same order as the order the connection was made, when the
+ signal is emitted.
The function returns true if it successfully connects the signal
to the slot. It will return false if it cannot create the
@@ -2385,9 +2385,13 @@ int QObject::receivers(const char *signal) const
existence of either \a signal or \a method, or if their signatures
aren't compatible.
- For every connection you make, a signal is emitted; two signals are emitted
- for duplicate connections. You can break all of these connections with a
- single disconnect() call.
+ 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 false
The optional \a type parameter describes the type of connection
to establish. In particular, it determines whether a particular
@@ -2520,7 +2524,8 @@ bool QObject::connect(const QObject *sender, const char *signal,
}
}
#endif
- QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
+ if (!QMetaObject::connect(sender, signal_index, receiver, method_index, type, types))
+ return false;
const_cast<QObject*>(sender)->connectNotify(signal - 1);
return true;
}
@@ -2771,6 +2776,22 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
QObject *s = const_cast<QObject *>(sender);
QObject *r = const_cast<QObject *>(receiver);
+ QOrderedMutexLocker locker(signalSlotLock(sender),
+ signalSlotLock(receiver));
+
+ if (type & Qt::UniqueConnection) {
+ QObjectConnectionListVector *connectionLists = s->d_func()->connectionLists;
+ if (connectionLists && connectionLists->count() > signal_index) {
+ QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal_index];
+ for (int i = 0; i < connectionList.count(); ++i) {
+ QObjectPrivate::Connection *c2 = connectionList.at(i);
+ if (c2->receiver == receiver && c2->method == method_index)
+ return false;
+ }
+ }
+ type &= Qt::UniqueConnection - 1;
+ }
+
QObjectPrivate::Connection *c = new QObjectPrivate::Connection;
c->sender = s;
c->receiver = r;
@@ -2778,9 +2799,6 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
c->connectionType = type;
c->argumentTypes = types;
- QOrderedMutexLocker locker(signalSlotLock(sender),
- signalSlotLock(receiver));
-
s->d_func()->addConnection(signal_index, c);
r->d_func()->senders.append(c);