Doc: Discuss the concept of thread affinity in more detail
[qt:qt.git] / src / corelib / kernel / qobject.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qobject.h"
43 #include "qobject_p.h"
44 #include "qmetaobject_p.h"
45
46 #include "qabstracteventdispatcher.h"
47 #include "qcoreapplication.h"
48 #include "qcoreapplication_p.h"
49 #include "qvariant.h"
50 #include "qmetaobject.h"
51 #include <qregexp.h>
52 #include <qthread.h>
53 #include <private/qthread_p.h>
54 #include <qdebug.h>
55 #include <qhash.h>
56 #include <qpair.h>
57 #include <qset.h>
58 #include <qsemaphore.h>
59 #include <qsharedpointer.h>
60
61 #include <private/qorderedmutexlocker_p.h>
62 #include <private/qmutexpool_p.h>
63
64 #include <new>
65
66 #include <ctype.h>
67 #include <limits.h>
68
69 QT_BEGIN_NAMESPACE
70
71 static int DIRECT_CONNECTION_ONLY = 0;
72
73 static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
74 {
75     int *types = new int [typeNames.count() + 1];
76     Q_CHECK_PTR(types);
77     for (int i = 0; i < typeNames.count(); ++i) {
78         const QByteArray typeName = typeNames.at(i);
79         if (typeName.endsWith('*'))
80             types[i] = QMetaType::VoidStar;
81         else
82             types[i] = QMetaType::type(typeName);
83
84         if (!types[i]) {
85             qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
86                      "(Make sure '%s' is registered using qRegisterMetaType().)",
87                      typeName.constData(), typeName.constData());
88             delete [] types;
89             return 0;
90         }
91     }
92     types[typeNames.count()] = 0;
93
94     return types;
95 }
96
97 static QBasicAtomicPointer<QMutexPool> signalSlotMutexes = Q_BASIC_ATOMIC_INITIALIZER(0);
98 static QBasicAtomicInt objectCount = Q_BASIC_ATOMIC_INITIALIZER(0);
99
100 /** \internal
101  * mutex to be locked when accessing the connectionlists or the senders list
102  */
103 static inline QMutex *signalSlotLock(const QObject *o)
104 {
105     if (!signalSlotMutexes) {
106         QMutexPool *mp = new QMutexPool;
107         if (!signalSlotMutexes.testAndSetOrdered(0, mp)) {
108             delete mp;
109         }
110     }
111     return signalSlotMutexes->get(o);
112 }
113
114 extern "C" Q_CORE_EXPORT void qt_addObject(QObject *)
115 {
116     objectCount.ref();
117 }
118
119 extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
120 {
121     if(!objectCount.deref()) {
122         QMutexPool *old = signalSlotMutexes.fetchAndStoreAcquire(0);
123         delete old;
124     }
125 }
126
127 void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
128 void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
129 void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0;
130
131 QObjectData::~QObjectData() {}
132
133 QObjectPrivate::QObjectPrivate(int version)
134     : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
135 {
136     if (version != QObjectPrivateVersion)
137         qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
138                 version, QObjectPrivateVersion);
139
140     // QObjectData initialization
141     q_ptr = 0;
142     parent = 0;                                 // no parent yet. It is set by setParent()
143     isWidget = false;                           // assume not a widget object
144     pendTimer = false;                          // no timers yet
145     blockSig = false;                           // not blocking signals
146     wasDeleted = false;                         // double-delete catcher
147     sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent
148     receiveChildEvents = true;
149     postedEvents = 0;
150     extraData = 0;
151     connectedSignals[0] = connectedSignals[1] = 0;
152     inThreadChangeEvent = false;
153 #ifdef QT_JAMBI_BUILD
154     inEventHandler = false;
155     deleteWatch = 0;
156 #endif
157     metaObject = 0;
158     hasGuards = false;
159 }
160
161 QObjectPrivate::~QObjectPrivate()
162 {
163     if (pendTimer) {
164         // unregister pending timers
165         if (threadData && threadData->eventDispatcher)
166             threadData->eventDispatcher->unregisterTimers(q_ptr);
167     }
168
169     if (postedEvents)
170         QCoreApplication::removePostedEvents(q_ptr, 0);
171
172     if (threadData)
173         threadData->deref();
174
175     delete static_cast<QAbstractDynamicMetaObject*>(metaObject);
176 #ifdef QT_JAMBI_BUILD
177     if (deleteWatch)
178         *deleteWatch = 1;
179 #endif
180 #ifndef QT_NO_USERDATA
181     if (extraData)
182         qDeleteAll(extraData->userData);
183     delete extraData;
184 #endif
185 }
186
187
188 #ifdef QT_JAMBI_BUILD
189 int *QObjectPrivate::setDeleteWatch(QObjectPrivate *d, int *w) {
190     int *old = d->deleteWatch;
191     d->deleteWatch = w;
192     return old;
193 }
194
195
196 void QObjectPrivate::resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch) {
197     if (!deleteWatch)
198         d->deleteWatch = oldWatch;
199
200     if (oldWatch)
201         *oldWatch = deleteWatch;
202 }
203 #endif
204
205 #ifdef QT3_SUPPORT
206 void QObjectPrivate::sendPendingChildInsertedEvents()
207 {
208     Q_Q(QObject);
209     for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {
210         QObject *c = pendingChildInsertedEvents.at(i).data();
211         if (!c || c->parent() != q)
212             continue;
213         QChildEvent childEvent(QEvent::ChildInserted, c);
214         QCoreApplication::sendEvent(q, &childEvent);
215     }
216     pendingChildInsertedEvents.clear();
217 }
218
219 #endif
220
221
222 /*!\internal
223   For a given metaobject, compute the signal offset, and the method offset (including signals)
224 */
225 static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int *methodOffset)
226 {
227     *signalOffset = *methodOffset = 0;
228     const QMetaObject *m = metaobject->d.superdata;
229     while (m) {
230         const QMetaObjectPrivate *d = QMetaObjectPrivate::get(m);
231         *methodOffset += d->methodCount;
232         *signalOffset += (d->revision >= 4) ? d->signalCount : d->methodCount;
233         /*Before Qt 4.6 (revision 4), the signalCount information was not generated by moc.
234            so for compatibility we consider all the method as slot for old moc output*/
235         m = m->d.superdata;
236     }
237 }
238
239 /*
240     This vector contains the all connections from an object.
241
242     Each object may have one vector containing the lists of
243     connections for a given signal. The index in the vector correspond
244     to the signal index. The signal index is the one returned by
245     QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal).
246     Negative index means connections to all signals.
247
248     This vector is protected by the object mutex (signalSlotMutexes())
249
250     Each Connection is also part of a 'senders' linked list. The mutex
251     of the receiver must be locked when touching the pointers of this
252     linked list.
253 */
254 class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList>
255 {
256 public:
257     bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse
258     bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
259     int inUse; //number of functions that are currently accessing this object or its connections
260     QObjectPrivate::ConnectionList allsignals;
261
262     QObjectConnectionListVector()
263         : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0)
264     { }
265
266     QObjectPrivate::ConnectionList &operator[](int at)
267     {
268         if (at < 0)
269             return allsignals;
270         return QVector<QObjectPrivate::ConnectionList>::operator[](at);
271     }
272 };
273
274 // Used by QAccessibleWidget
275 bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
276 {
277     Q_Q(const QObject);
278     int signal_index = signalIndex(signal);
279     if (signal_index < 0)
280         return false;
281     QMutexLocker locker(signalSlotLock(q));
282     if (connectionLists) {
283         if (signal_index < connectionLists->count()) {
284             const QObjectPrivate::Connection *c =
285                 connectionLists->at(signal_index).first;
286
287             while (c) {
288                 if (c->receiver == receiver)
289                     return true;
290                 c = c->nextConnectionList;
291             }
292         }
293     }
294     return false;
295 }
296
297 // Used by QAccessibleWidget
298 QObjectList QObjectPrivate::receiverList(const char *signal) const
299 {
300     Q_Q(const QObject);
301     QObjectList returnValue;
302     int signal_index = signalIndex(signal);
303     if (signal_index < 0)
304         return returnValue;
305     QMutexLocker locker(signalSlotLock(q));
306     if (connectionLists) {
307         if (signal_index < connectionLists->count()) {
308             const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first;
309
310             while (c) {
311                 if (c->receiver)
312                     returnValue << c->receiver;
313                 c = c->nextConnectionList;
314             }
315         }
316     }
317     return returnValue;
318 }
319
320 // Used by QAccessibleWidget
321 QObjectList QObjectPrivate::senderList() const
322 {
323     QObjectList returnValue;
324     QMutexLocker locker(signalSlotLock(q_func()));
325     for (Connection *c = senders; c; c = c->next)
326         returnValue << c->sender;
327     return returnValue;
328 }
329
330 void QObjectPrivate::addConnection(int signal, Connection *c)
331 {
332     if (!connectionLists)
333         connectionLists = new QObjectConnectionListVector();
334     if (signal >= connectionLists->count())
335         connectionLists->resize(signal + 1);
336
337     ConnectionList &connectionList = (*connectionLists)[signal];
338     if (connectionList.last) {
339         connectionList.last->nextConnectionList = c;
340     } else {
341         connectionList.first = c;
342     }
343     connectionList.last = c;
344
345     cleanConnectionLists();
346 }
347
348 void QObjectPrivate::cleanConnectionLists()
349 {
350     if (connectionLists->dirty && !connectionLists->inUse) {
351         // remove broken connections
352         for (int signal = -1; signal < connectionLists->count(); ++signal) {
353             QObjectPrivate::ConnectionList &connectionList =
354                 (*connectionLists)[signal];
355
356             // Set to the last entry in the connection list that was *not*
357             // deleted.  This is needed to update the list's last pointer
358             // at the end of the cleanup.
359             QObjectPrivate::Connection *last = 0;
360
361             QObjectPrivate::Connection **prev = &connectionList.first;
362             QObjectPrivate::Connection *c = *prev;
363             while (c) {
364                 if (c->receiver) {
365                     last = c;
366                     prev = &c->nextConnectionList;
367                     c = *prev;
368                 } else {
369                     QObjectPrivate::Connection *next = c->nextConnectionList;
370                     *prev = next;
371                     delete c;
372                     c = next;
373                 }
374             }
375
376             // Correct the connection list's last pointer.
377             // As conectionList.last could equal last, this could be a noop
378             connectionList.last = last;
379         }
380         connectionLists->dirty = false;
381     }
382 }
383
384 typedef QMultiHash<QObject *, QObject **> GuardHash;
385 Q_GLOBAL_STATIC(GuardHash, guardHash)
386 Q_GLOBAL_STATIC(QMutex, guardHashLock)
387
388 /*!\internal
389  */
390 void QMetaObject::addGuard(QObject **ptr)
391 {
392     if (!*ptr)
393         return;
394     GuardHash *hash = guardHash();
395     if (!hash) {
396         *ptr = 0;
397         return;
398     }
399     QMutexLocker locker(guardHashLock());
400     QObjectPrivate::get(*ptr)->hasGuards = true;
401     hash->insert(*ptr, ptr);
402 }
403
404 /*!\internal
405  */
406 void QMetaObject::removeGuard(QObject **ptr)
407 {
408     if (!*ptr)
409         return;
410     GuardHash *hash = guardHash();
411     /* check that the hash is empty - otherwise we might detach
412        the shared_null hash, which will alloc, which is not nice */
413     if (!hash || hash->isEmpty())
414         return;
415     QMutexLocker locker(guardHashLock());
416     if (!*ptr) //check again, under the lock
417         return;
418     GuardHash::iterator it = hash->find(*ptr);
419     const GuardHash::iterator end = hash->end();
420     bool more = false; //if the QObject has more pointer attached to it.
421     for (; it.key() == *ptr && it != end; ++it) {
422         if (it.value() == ptr) {
423             it = hash->erase(it);
424             if (!more) more = (it != end && it.key() == *ptr);
425             break;
426         }
427         more = true;
428     }
429     if (!more)
430         QObjectPrivate::get(*ptr)->hasGuards = false;
431 }
432
433 /*!\internal
434  */
435 void QMetaObject::changeGuard(QObject **ptr, QObject *o)
436 {
437     GuardHash *hash = guardHash();
438     if (!hash) {
439         *ptr = 0;
440         return;
441     }
442     QMutexLocker locker(guardHashLock());
443     if (o) {
444         hash->insert(o, ptr);
445         QObjectPrivate::get(o)->hasGuards = true;
446     }
447     if (*ptr) {
448         bool more = false; //if the QObject has more pointer attached to it.
449         GuardHash::iterator it = hash->find(*ptr);
450         const GuardHash::iterator end = hash->end();
451         for (; it.key() == *ptr && it != end; ++it) {
452             if (it.value() == ptr) {
453                 it = hash->erase(it);
454                 if (!more) more = (it != end && it.key() == *ptr);
455                 break;
456             }
457             more = true;
458         }
459         if (!more)
460             QObjectPrivate::get(*ptr)->hasGuards = false;
461     }
462     *ptr = o;
463 }
464
465 /*! \internal
466  */
467 void QObjectPrivate::clearGuards(QObject *object)
468 {
469     GuardHash *hash = 0;
470     QMutex *mutex = 0;
471     QT_TRY {
472         hash = guardHash();
473         mutex = guardHashLock();
474     } QT_CATCH(const std::bad_alloc &) {
475         // do nothing in case of OOM - code below is safe
476     }
477
478     /* check that the hash is empty - otherwise we might detach
479        the shared_null hash, which will alloc, which is not nice */
480     if (hash && !hash->isEmpty()) {
481         QMutexLocker locker(mutex);
482         GuardHash::iterator it = hash->find(object);
483         const GuardHash::iterator end = hash->end();
484         while (it.key() == object && it != end) {
485             *it.value() = 0;
486             it = hash->erase(it);
487         }
488     }
489 }
490
491 /*! \internal
492  */
493 QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
494                                const QObject *sender, int signalId,
495                                int nargs, int *types, void **args, QSemaphore *semaphore)
496     : QEvent(MetaCall), sender_(sender), signalId_(signalId),
497       nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
498       callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
499 { }
500
501 /*! \internal
502  */
503 QMetaCallEvent::~QMetaCallEvent()
504 {
505     if (types_) {
506         for (int i = 0; i < nargs_; ++i) {
507             if (types_[i] && args_[i])
508                 QMetaType::destroy(types_[i], args_[i]);
509         }
510         qFree(types_);
511         qFree(args_);
512     }
513 #ifndef QT_NO_THREAD
514     if (semaphore_)
515         semaphore_->release();
516 #endif
517 }
518
519 /*! \internal
520  */
521 void QMetaCallEvent::placeMetaCall(QObject *object)
522 {
523     if (callFunction_) {
524         callFunction_(object, QMetaObject::InvokeMetaMethod, method_relative_, args_);
525     } else {
526         QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method_offset_ + method_relative_, args_);
527     }
528 }
529
530 /*!
531     \class QObject
532     \brief The QObject class is the base class of all Qt objects.
533
534     \ingroup objectmodel
535
536     \reentrant
537
538     QObject is the heart of the Qt \l{Object Model}. The central
539     feature in this model is a very powerful mechanism for seamless
540     object communication called \l{signals and slots}. You can
541     connect a signal to a slot with connect() and destroy the
542     connection with disconnect(). To avoid never ending notification
543     loops you can temporarily block signals with blockSignals(). The
544     protected functions connectNotify() and disconnectNotify() make
545     it possible to track connections.
546
547     QObjects organize themselves in \l {Object Trees & Ownership}
548     {object trees}. When you create a QObject with another object as
549     parent, the object will automatically add itself to the parent's
550     children() list. The parent takes ownership of the object; i.e.,
551     it will automatically delete its children in its destructor. You
552     can look for an object by name and optionally type using
553     findChild() or findChildren().
554
555     Every object has an objectName() and its class name can be found
556     via the corresponding metaObject() (see QMetaObject::className()).
557     You can determine whether the object's class inherits another
558     class in the QObject inheritance hierarchy by using the
559     inherits() function.
560
561     When an object is deleted, it emits a destroyed() signal. You can
562     catch this signal to avoid dangling references to QObjects.
563
564     QObjects can receive events through event() and filter the events
565     of other objects. See installEventFilter() and eventFilter() for
566     details. A convenience handler, childEvent(), can be reimplemented
567     to catch child events.
568
569     Last but not least, QObject provides the basic timer support in
570     Qt; see QTimer for high-level support for timers.
571
572     Notice that the Q_OBJECT macro is mandatory for any object that
573     implements signals, slots or properties. You also need to run the
574     \l{moc}{Meta Object Compiler} on the source file. We strongly
575     recommend the use of this macro in all subclasses of QObject
576     regardless of whether or not they actually use signals, slots and
577     properties, since failure to do so may lead certain functions to
578     exhibit strange behavior.
579
580     All Qt widgets inherit QObject. The convenience function
581     isWidgetType() returns whether an object is actually a widget. It
582     is much faster than
583     \l{qobject_cast()}{qobject_cast}<QWidget *>(\e{obj}) or
584     \e{obj}->\l{inherits()}{inherits}("QWidget").
585
586     Some QObject functions, e.g. children(), return a QObjectList.
587     QObjectList is a typedef for QList<QObject *>.
588
589     \section1 Thread Affinity
590
591     A QObject instance is said to have a \e{thread affinity}, or that
592     it \e{lives} in a certain thread. When a QObject receives a
593     \l{Qt::QueuedConnection}{queued signal} or a \l{The Event
594     System#Sending Events}{posted event}, the slot or event handler
595     will run in the thread that the object lives in.
596
597     \note If a QObject has no thread affinity (that is, if thread()
598     returns zero), or if it lives in a thread that has no running event
599     loop, then it cannot receive queued signals or posted events.
600
601     By default, a QObject lives in the thread in which it is created.
602     An object's thread affinity can be queried using thread() and
603     changed using moveToThread().
604
605     All QObjects must live in the same thread as their parent. Consequently:
606
607     \list
608     \li setParent() will fail if the two QObjects involved live in
609         different threads.
610     \li When a QObject is moved to another thread, all its children
611         will be automatically moved too.
612     \li moveToThread() will fail if the QObject has a parent.
613     \li If \l{QObject}s are created within QThread::run(), they cannot
614         become children of the QThread object because the QThread does
615         not live in the thread that calls QThread::run().
616     \endlist
617
618     \note A QObject's member variables \e{do not} automatically become
619     its children. The parent-child relationship must be set by either
620     passing a pointer to the child's \l{QObject()}{constructor}, or by
621     calling setParent(). Without this step, the object's member variables
622     will remain in the old thread when moveToThread() is called.
623
624     \target No copy constructor
625     \section1 No copy constructor or assignment operator
626
627     QObject has neither a copy constructor nor an assignment operator.
628     This is by design. Actually, they are declared, but in a
629     \c{private} section with the macro Q_DISABLE_COPY(). In fact, all
630     Qt classes derived from QObject (direct or indirect) use this
631     macro to declare their copy constructor and assignment operator to
632     be private. The reasoning is found in the discussion on
633     \l{Identity vs Value} {Identity vs Value} on the Qt \l{Object
634     Model} page.
635
636     The main consequence is that you should use pointers to QObject
637     (or to your QObject subclass) where you might otherwise be tempted
638     to use your QObject subclass as a value. For example, without a
639     copy constructor, you can't use a subclass of QObject as the value
640     to be stored in one of the container classes. You must store
641     pointers.
642
643     \section1 Auto-Connection
644
645     Qt's meta-object system provides a mechanism to automatically connect
646     signals and slots between QObject subclasses and their children. As long
647     as objects are defined with suitable object names, and slots follow a
648     simple naming convention, this connection can be performed at run-time
649     by the QMetaObject::connectSlotsByName() function.
650
651     \l uic generates code that invokes this function to enable
652     auto-connection to be performed between widgets on forms created
653     with \QD. More information about using auto-connection with \QD is
654     given in the \l{Using a Designer UI File in Your Application} section of
655     the \QD manual.
656
657     \section1 Dynamic Properties
658
659     From Qt 4.2, dynamic properties can be added to and removed from QObject
660     instances at run-time. Dynamic properties do not need to be declared at
661     compile-time, yet they provide the same advantages as static properties
662     and are manipulated using the same API - using property() to read them
663     and setProperty() to write them.
664
665     From Qt 4.3, dynamic properties are supported by
666     \l{Qt Designer's Widget Editing Mode#The Property Editor}{Qt Designer},
667     and both standard Qt widgets and user-created forms can be given dynamic
668     properties.
669
670     \section1 Internationalization (i18n)
671
672     All QObject subclasses support Qt's translation features, making it possible
673     to translate an application's user interface into different languages.
674
675     To make user-visible text translatable, it must be wrapped in calls to
676     the tr() function. This is explained in detail in the
677     \l{Writing Source Code for Translation} document.
678
679     \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
680     \sa {Object Trees & Ownership}
681 */
682
683 /*!
684     \relates QObject
685
686     Returns a pointer to the object named \a name that inherits \a
687     type and with a given \a parent.
688
689     Returns 0 if there is no such child.
690
691     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 0
692 */
693
694 void *qt_find_obj_child(QObject *parent, const char *type, const QString &name)
695 {
696     QObjectList list = parent->children();
697     if (list.size() == 0) return 0;
698     for (int i = 0; i < list.size(); ++i) {
699         QObject *obj = list.at(i);
700         if (name == obj->objectName() && obj->inherits(type))
701             return obj;
702     }
703     return 0;
704 }
705
706
707 /*****************************************************************************
708   QObject member functions
709  *****************************************************************************/
710
711 // check the constructor's parent thread argument
712 static bool check_parent_thread(QObject *parent,
713                                 QThreadData *parentThreadData,
714                                 QThreadData *currentThreadData)
715 {
716     if (parent && parentThreadData != currentThreadData) {
717         QThread *parentThread = parentThreadData->thread;
718         QThread *currentThread = currentThreadData->thread;
719         qWarning("QObject: Cannot create children for a parent that is in a different thread.\n"
720                  "(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)",
721                  parent->metaObject()->className(),
722                  parent,
723                  parentThread ? parentThread->metaObject()->className() : "QThread",
724                  parentThread,
725                  currentThread ? currentThread->metaObject()->className() : "QThread",
726                  currentThread);
727         return false;
728     }
729     return true;
730 }
731
732 /*!
733     Constructs an object with parent object \a parent.
734
735     The parent of an object may be viewed as the object's owner. For
736     instance, a \l{QDialog}{dialog box} is the parent of the \gui OK
737     and \gui Cancel buttons it contains.
738
739     The destructor of a parent object destroys all child objects.
740
741     Setting \a parent to 0 constructs an object with no parent. If the
742     object is a widget, it will become a top-level window.
743
744     \sa parent(), findChild(), findChildren()
745 */
746
747 QObject::QObject(QObject *parent)
748     : d_ptr(new QObjectPrivate)
749 {
750     Q_D(QObject);
751     d_ptr->q_ptr = this;
752     d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
753     d->threadData->ref();
754     if (parent) {
755         QT_TRY {
756             if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
757                 parent = 0;
758             setParent(parent);
759         } QT_CATCH(...) {
760             d->threadData->deref();
761             QT_RETHROW;
762         }
763     }
764     qt_addObject(this);
765 }
766
767 #ifdef QT3_SUPPORT
768 /*!
769     \overload QObject()
770     \obsolete
771
772     Creates a new QObject with the given \a parent and object \a name.
773  */
774 QObject::QObject(QObject *parent, const char *name)
775     : d_ptr(new QObjectPrivate)
776 {
777     Q_D(QObject);
778     qt_addObject(d_ptr->q_ptr = this);
779     d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
780     d->threadData->ref();
781     if (parent) {
782         if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
783             parent = 0;
784         setParent(parent);
785     }
786     setObjectName(QString::fromAscii(name));
787 }
788 #endif
789
790 /*! \internal
791  */
792 QObject::QObject(QObjectPrivate &dd, QObject *parent)
793     : d_ptr(&dd)
794 {
795     Q_D(QObject);
796     d_ptr->q_ptr = this;
797     d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
798     d->threadData->ref();
799     if (parent) {
800         QT_TRY {
801             if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
802                 parent = 0;
803             if (d->isWidget) {
804                 if (parent) {
805                     d->parent = parent;
806                     d->parent->d_func()->children.append(this);
807                 }
808                 // no events sent here, this is done at the end of the QWidget constructor
809             } else {
810                 setParent(parent);
811             }
812         } QT_CATCH(...) {
813             d->threadData->deref();
814             QT_RETHROW;
815         }
816     }
817     qt_addObject(this);
818 }
819
820 /*!
821     Destroys the object, deleting all its child objects.
822
823     All signals to and from the object are automatically disconnected, and
824     any pending posted events for the object are removed from the event
825     queue. However, it is often safer to use deleteLater() rather than
826     deleting a QObject subclass directly.
827
828     \warning All child objects are deleted. If any of these objects
829     are on the stack or global, sooner or later your program will
830     crash. We do not recommend holding pointers to child objects from
831     outside the parent. If you still do, the destroyed() signal gives
832     you an opportunity to detect when an object is destroyed.
833
834     \warning Deleting a QObject while pending events are waiting to
835     be delivered can cause a crash. You must not delete the QObject
836     directly if it exists in a different thread than the one currently
837     executing. Use deleteLater() instead, which will cause the event
838     loop to delete the object after all pending events have been
839     delivered to it.
840
841     \sa deleteLater()
842 */
843
844 QObject::~QObject()
845 {
846     Q_D(QObject);
847     d->wasDeleted = true;
848     d->blockSig = 0; // unblock signals so we always emit destroyed()
849
850     if (d->hasGuards && !d->isWidget) {
851         // set all QPointers for this object to zero - note that
852         // ~QWidget() does this for us, so we don't have to do it twice
853         QObjectPrivate::clearGuards(this);
854     }
855
856     if (d->sharedRefcount) {
857         if (d->sharedRefcount->strongref > 0) {
858             qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash.");
859             // but continue deleting, it's too late to stop anyway
860         }
861
862         // indicate to all QWeakPointers that this QObject has now been deleted
863         d->sharedRefcount->strongref = 0;
864         if (!d->sharedRefcount->weakref.deref())
865             delete d->sharedRefcount;
866     }
867
868
869     if (d->isSignalConnected(0)) {
870         QT_TRY {
871             emit destroyed(this);
872         } QT_CATCH(...) {
873             // all the signal/slots connections are still in place - if we don't
874             // quit now, we will crash pretty soon.
875             qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
876             QT_RETHROW;
877         }
878     }
879
880     if (d->declarativeData)
881         QAbstractDeclarativeData::destroyed(d->declarativeData, this);
882
883     // set ref to zero to indicate that this object has been deleted
884     if (d->currentSender != 0)
885         d->currentSender->ref = 0;
886     d->currentSender = 0;
887
888     if (d->connectionLists || d->senders) {
889         QMutex *signalSlotMutex = signalSlotLock(this);
890         QMutexLocker locker(signalSlotMutex);
891
892         // disconnect all receivers
893         if (d->connectionLists) {
894             ++d->connectionLists->inUse;
895             int connectionListsCount = d->connectionLists->count();
896             for (int signal = -1; signal < connectionListsCount; ++signal) {
897                 QObjectPrivate::ConnectionList &connectionList =
898                     (*d->connectionLists)[signal];
899
900                 while (QObjectPrivate::Connection *c = connectionList.first) {
901                     if (!c->receiver) {
902                         connectionList.first = c->nextConnectionList;
903                         delete c;
904                         continue;
905                     }
906
907                     QMutex *m = signalSlotLock(c->receiver);
908                     bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
909
910                     if (c->receiver) {
911                         *c->prev = c->next;
912                         if (c->next) c->next->prev = c->prev;
913                     }
914                     if (needToUnlock)
915                         m->unlockInline();
916
917                     connectionList.first = c->nextConnectionList;
918                     delete c;
919                 }
920             }
921
922             if (!--d->connectionLists->inUse) {
923                 delete d->connectionLists;
924             } else {
925                 d->connectionLists->orphaned = true;
926             }
927             d->connectionLists = 0;
928         }
929
930         // disconnect all senders
931         QObjectPrivate::Connection *node = d->senders;
932         while (node) {
933             QObject *sender = node->sender;
934             QMutex *m = signalSlotLock(sender);
935             node->prev = &node;
936             bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
937             //the node has maybe been removed while the mutex was unlocked in relock?
938             if (!node || node->sender != sender) {
939                 m->unlockInline();
940                 continue;
941             }
942             node->receiver = 0;
943             QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
944             if (senderLists)
945                 senderLists->dirty = true;
946
947             node = node->next;
948             if (needToUnlock)
949                 m->unlockInline();
950         }
951     }
952
953     if (!d->children.isEmpty())
954         d->deleteChildren();
955
956     qt_removeObject(this);
957
958     if (d->parent)        // remove it from parent object
959         d->setParent_helper(0);
960
961 #ifdef QT_JAMBI_BUILD
962     if (d->inEventHandler) {
963         qWarning("QObject: Do not delete object, '%s', during its event handler!",
964                  objectName().isNull() ? "unnamed" : qPrintable(objectName()));
965     }
966 #endif
967 }
968
969 QObjectPrivate::Connection::~Connection()
970 {
971     if (argumentTypes != &DIRECT_CONNECTION_ONLY)
972         delete [] static_cast<int *>(argumentTypes);
973 }
974
975
976 /*!
977     \fn QMetaObject *QObject::metaObject() const
978
979     Returns a pointer to the meta-object of this object.
980
981     A meta-object contains information about a class that inherits
982     QObject, e.g. class name, superclass name, properties, signals and
983     slots. Every QObject subclass that contains the Q_OBJECT macro will have a
984     meta-object.
985
986     The meta-object information is required by the signal/slot
987     connection mechanism and the property system. The inherits()
988     function also makes use of the meta-object.
989
990     If you have no pointer to an actual object instance but still
991     want to access the meta-object of a class, you can use \l
992     staticMetaObject.
993
994     Example:
995
996     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 1
997
998     \sa staticMetaObject
999 */
1000
1001 /*!
1002     \variable QObject::staticMetaObject
1003
1004     This variable stores the meta-object for the class.
1005
1006     A meta-object contains information about a class that inherits
1007     QObject, e.g. class name, superclass name, properties, signals and
1008     slots. Every class that contains the Q_OBJECT macro will also have
1009     a meta-object.
1010
1011     The meta-object information is required by the signal/slot
1012     connection mechanism and the property system. The inherits()
1013     function also makes use of the meta-object.
1014
1015     If you have a pointer to an object, you can use metaObject() to
1016     retrieve the meta-object associated with that object.
1017
1018     Example:
1019
1020     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 2
1021
1022     \sa metaObject()
1023 */
1024
1025 /*! \fn T *qobject_cast<T *>(QObject *object)
1026     \relates QObject
1027
1028     Returns the given \a object cast to type T if the object is of type
1029     T (or of a subclass); otherwise returns 0.  If \a object is 0 then 
1030     it will also return 0.
1031
1032     The class T must inherit (directly or indirectly) QObject and be
1033     declared with the \l Q_OBJECT macro.
1034
1035     A class is considered to inherit itself.
1036
1037     Example:
1038
1039     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 3
1040
1041     The qobject_cast() function behaves similarly to the standard C++
1042     \c dynamic_cast(), with the advantages that it doesn't require
1043     RTTI support and it works across dynamic library boundaries.
1044
1045     qobject_cast() can also be used in conjunction with interfaces;
1046     see the \l{tools/plugandpaint}{Plug & Paint} example for details.
1047
1048     \warning If T isn't declared with the Q_OBJECT macro, this
1049     function's return value is undefined.
1050
1051     \sa QObject::inherits()
1052 */
1053
1054 /*!
1055     \fn bool QObject::inherits(const char *className) const
1056
1057     Returns true if this object is an instance of a class that
1058     inherits \a className or a QObject subclass that inherits \a
1059     className; otherwise returns false.
1060
1061     A class is considered to inherit itself.
1062
1063     Example:
1064
1065     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 4
1066
1067     If you need to determine whether an object is an instance of a particular
1068     class for the purpose of casting it, consider using qobject_cast<Type *>(object)
1069     instead.
1070
1071     \sa metaObject(), qobject_cast()
1072 */
1073
1074 /*!
1075     \property QObject::objectName
1076
1077     \brief the name of this object
1078
1079     You can find an object by name (and type) using findChild(). You can
1080     find a set of objects with findChildren().
1081
1082     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 5
1083
1084     By default, this property contains an empty string.
1085
1086     \sa metaObject(), QMetaObject::className()
1087 */
1088
1089 QString QObject::objectName() const
1090 {
1091     Q_D(const QObject);
1092     return d->objectName;
1093 }
1094
1095 /*
1096     Sets the object's name to \a name.
1097 */
1098 void QObject::setObjectName(const QString &name)
1099 {
1100     Q_D(QObject);
1101     bool objectNameChanged = d->declarativeData && d->objectName != name;
1102
1103     d->objectName = name;
1104
1105     if (objectNameChanged) 
1106         d->declarativeData->objectNameChanged(d->declarativeData, this);
1107 }
1108
1109
1110 #ifdef QT3_SUPPORT
1111 /*! \internal
1112     QObject::child is compat but needs to call itself recursively,
1113     that's why we need this helper.
1114 */
1115 static QObject *qChildHelper(const char *objName, const char *inheritsClass,
1116                              bool recursiveSearch, const QObjectList &children)
1117 {
1118     if (children.isEmpty())
1119         return 0;
1120
1121     bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
1122     const QLatin1String oName(objName);
1123     for (int i = 0; i < children.size(); ++i) {
1124         QObject *obj = children.at(i);
1125         if (onlyWidgets) {
1126             if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
1127                 return obj;
1128         } else if ((!inheritsClass || obj->inherits(inheritsClass))
1129                    && (!objName || obj->objectName() == oName))
1130             return obj;
1131         if (recursiveSearch && (obj = qChildHelper(objName, inheritsClass,
1132                                                    recursiveSearch, obj->children())))
1133             return obj;
1134     }
1135     return 0;
1136 }
1137
1138
1139 /*!
1140     Searches the children and optionally grandchildren of this object,
1141     and returns a child that is called \a objName that inherits \a
1142     inheritsClass. If \a inheritsClass is 0 (the default), any class
1143     matches.
1144
1145     If \a recursiveSearch is true (the default), child() performs a
1146     depth-first search of the object's children.
1147
1148     If there is no such object, this function returns 0. If there are
1149     more than one, the first one found is returned.
1150 */
1151 QObject* QObject::child(const char *objName, const char *inheritsClass,
1152                         bool recursiveSearch) const
1153 {
1154     Q_D(const QObject);
1155     return qChildHelper(objName, inheritsClass, recursiveSearch, d->children);
1156 }
1157 #endif
1158
1159 /*!
1160     \fn bool QObject::isWidgetType() const
1161
1162     Returns true if the object is a widget; otherwise returns false.
1163
1164     Calling this function is equivalent to calling
1165     inherits("QWidget"), except that it is much faster.
1166 */
1167
1168
1169 /*!
1170     This virtual function receives events to an object and should
1171     return true if the event \a e was recognized and processed.
1172
1173     The event() function can be reimplemented to customize the
1174     behavior of an object.
1175
1176     \sa installEventFilter(), timerEvent(), QApplication::sendEvent(),
1177     QApplication::postEvent(), QWidget::event()
1178 */
1179
1180 bool QObject::event(QEvent *e)
1181 {
1182     switch (e->type()) {
1183     case QEvent::Timer:
1184         timerEvent((QTimerEvent*)e);
1185         break;
1186
1187 #ifdef QT3_SUPPORT
1188     case QEvent::ChildInsertedRequest:
1189         d_func()->sendPendingChildInsertedEvents();
1190         break;
1191 #endif
1192
1193     case QEvent::ChildAdded:
1194     case QEvent::ChildPolished:
1195 #ifdef QT3_SUPPORT
1196     case QEvent::ChildInserted:
1197 #endif
1198     case QEvent::ChildRemoved:
1199         childEvent((QChildEvent*)e);
1200         break;
1201
1202     case QEvent::DeferredDelete:
1203         qDeleteInEventHandler(this);
1204         break;
1205
1206     case QEvent::MetaCall:
1207         {
1208 #ifdef QT_JAMBI_BUILD
1209             d_func()->inEventHandler = false;
1210 #endif
1211             QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
1212             QObjectPrivate::Sender currentSender;
1213             currentSender.sender = const_cast<QObject*>(mce->sender());
1214             currentSender.signal = mce->signalId();
1215             currentSender.ref = 1;
1216             QObjectPrivate::Sender * const previousSender =
1217                 QObjectPrivate::setCurrentSender(this, &currentSender);
1218 #if defined(QT_NO_EXCEPTIONS)
1219             mce->placeMetaCall(this);
1220 #else
1221             QT_TRY {
1222                 mce->placeMetaCall(this);
1223             } QT_CATCH(...) {
1224                 QObjectPrivate::resetCurrentSender(this, &currentSender, previousSender);
1225                 QT_RETHROW;
1226             }
1227 #endif
1228             QObjectPrivate::resetCurrentSender(this, &currentSender, previousSender);
1229             break;
1230         }
1231
1232     case QEvent::ThreadChange: {
1233         Q_D(QObject);
1234         QThreadData *threadData = d->threadData;
1235         QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
1236         if (eventDispatcher) {
1237             QList<QPair<int, int> > timers = eventDispatcher->registeredTimers(this);
1238             if (!timers.isEmpty()) {
1239                 // set inThreadChangeEvent to true to tell the dispatcher not to release out timer ids
1240                 // back to the pool (since the timer ids are moving to a new thread).
1241                 d->inThreadChangeEvent = true;
1242                 eventDispatcher->unregisterTimers(this);
1243                 d->inThreadChangeEvent = false;
1244                 QMetaObject::invokeMethod(this, "_q_reregisterTimers", Qt::QueuedConnection,
1245                                           Q_ARG(void*, (new QList<QPair<int, int> >(timers))));
1246             }
1247         }
1248         break;
1249     }
1250
1251     default:
1252         if (e->type() >= QEvent::User) {
1253             customEvent(e);
1254             break;
1255         }
1256         return false;
1257     }
1258     return true;
1259 }
1260
1261 /*!
1262     \fn void QObject::timerEvent(QTimerEvent *event)
1263
1264     This event handler can be reimplemented in a subclass to receive
1265     timer events for the object.
1266
1267     QTimer provides a higher-level interface to the timer
1268     functionality, and also more general information about timers. The
1269     timer event is passed in the \a event parameter.
1270
1271     \sa startTimer(), killTimer(), event()
1272 */
1273
1274 void QObject::timerEvent(QTimerEvent *)
1275 {
1276 }
1277
1278
1279 /*!
1280     This event handler can be reimplemented in a subclass to receive
1281     child events. The event is passed in the \a event parameter.
1282
1283     QEvent::ChildAdded and QEvent::ChildRemoved events are sent to
1284     objects when children are added or removed. In both cases you can
1285     only rely on the child being a QObject, or if isWidgetType()
1286     returns true, a QWidget. (This is because, in the
1287     \l{QEvent::ChildAdded}{ChildAdded} case, the child is not yet
1288     fully constructed, and in the \l{QEvent::ChildRemoved}{ChildRemoved}
1289     case it might have been destructed already).
1290
1291     QEvent::ChildPolished events are sent to widgets when children
1292     are polished, or when polished children are added. If you receive
1293     a child polished event, the child's construction is usually
1294     completed. However, this is not guaranteed, and multiple polish
1295     events may be delivered during the execution of a widget's
1296     constructor.
1297
1298     For every child widget, you receive one
1299     \l{QEvent::ChildAdded}{ChildAdded} event, zero or more
1300     \l{QEvent::ChildPolished}{ChildPolished} events, and one
1301     \l{QEvent::ChildRemoved}{ChildRemoved} event.
1302
1303     The \l{QEvent::ChildPolished}{ChildPolished} event is omitted if
1304     a child is removed immediately after it is added. If a child is
1305     polished several times during construction and destruction, you
1306     may receive several child polished events for the same child,
1307     each time with a different virtual table.
1308
1309     \sa event()
1310 */
1311
1312 void QObject::childEvent(QChildEvent * /* event */)
1313 {
1314 }
1315
1316
1317 /*!
1318     This event handler can be reimplemented in a subclass to receive
1319     custom events. Custom events are user-defined events with a type
1320     value at least as large as the QEvent::User item of the
1321     QEvent::Type enum, and is typically a QEvent subclass. The event
1322     is passed in the \a event parameter.
1323
1324     \sa event(), QEvent
1325 */
1326 void QObject::customEvent(QEvent * /* event */)
1327 {
1328 }
1329
1330
1331
1332 /*!
1333     Filters events if this object has been installed as an event
1334     filter for the \a watched object.
1335
1336     In your reimplementation of this function, if you want to filter
1337     the \a event out, i.e. stop it being handled further, return
1338     true; otherwise return false.
1339
1340     Example:
1341     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 6
1342
1343     Notice in the example above that unhandled events are passed to
1344     the base class's eventFilter() function, since the base class
1345     might have reimplemented eventFilter() for its own internal
1346     purposes.
1347
1348     \warning If you delete the receiver object in this function, be
1349     sure to return true. Otherwise, Qt will forward the event to the
1350     deleted object and the program might crash.
1351
1352     \sa installEventFilter()
1353 */
1354
1355 bool QObject::eventFilter(QObject * /* watched */, QEvent * /* event */)
1356 {
1357     return false;
1358 }
1359
1360 /*!
1361     \fn bool QObject::signalsBlocked() const
1362
1363     Returns true if signals are blocked; otherwise returns false.
1364
1365     Signals are not blocked by default.
1366
1367     \sa blockSignals()
1368 */
1369
1370 /*!
1371     If \a block is true, signals emitted by this object are blocked
1372     (i.e., emitting a signal will not invoke anything connected to it).
1373     If \a block is false, no such blocking will occur.
1374
1375     The return value is the previous value of signalsBlocked().
1376
1377     Note that the destroyed() signal will be emitted even if the signals
1378     for this object have been blocked.
1379
1380     \sa signalsBlocked()
1381 */
1382
1383 bool QObject::blockSignals(bool block)
1384 {
1385     Q_D(QObject);
1386     bool previous = d->blockSig;
1387     d->blockSig = block;
1388     return previous;
1389 }
1390
1391 /*!
1392     Returns the thread in which the object lives.
1393
1394     \sa moveToThread()
1395 */
1396 QThread *QObject::thread() const
1397 {
1398     return d_func()->threadData->thread;
1399 }
1400
1401 /*!
1402     Changes the thread affinity for this object and its children. The
1403     object cannot be moved if it has a parent. Event processing will
1404     continue in the \a targetThread.
1405
1406     To move an object to the main thread, use QApplication::instance()
1407     to retrieve a pointer to the current application, and then use
1408     QApplication::thread() to retrieve the thread in which the
1409     application lives. For example:
1410
1411     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 7
1412
1413     If \a targetThread is zero, all event processing for this object
1414     and its children stops.
1415
1416     Note that all active timers for the object will be reset. The
1417     timers are first stopped in the current thread and restarted (with
1418     the same interval) in the \a targetThread. As a result, constantly
1419     moving an object between threads can postpone timer events
1420     indefinitely.
1421
1422     A QEvent::ThreadChange event is sent to this object just before
1423     the thread affinity is changed. You can handle this event to
1424     perform any special processing. Note that any new events that are
1425     posted to this object will be handled in the \a targetThread.
1426
1427     \warning This function is \e not thread-safe; the current thread
1428     must be same as the current thread affinity. In other words, this
1429     function can only "push" an object from the current thread to
1430     another thread, it cannot "pull" an object from any arbitrary
1431     thread to the current thread.
1432
1433     \sa thread()
1434  */
1435 void QObject::moveToThread(QThread *targetThread)
1436 {
1437     Q_D(QObject);
1438
1439     if (d->threadData->thread == targetThread) {
1440         // object is already in this thread
1441         return;
1442     }
1443
1444     if (d->parent != 0) {
1445         qWarning("QObject::moveToThread: Cannot move objects with a parent");
1446         return;
1447     }
1448     if (d->isWidget) {
1449         qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread");
1450         return;
1451     }
1452
1453     QThreadData *currentData = QThreadData::current();
1454     QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0);
1455     if (d->threadData->thread == 0 && currentData == targetData) {
1456         // one exception to the rule: we allow moving objects with no thread affinity to the current thread
1457         currentData = d->threadData;
1458     } else if (d->threadData != currentData) {
1459         qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n"
1460                  "Cannot move to target thread (%p)\n",
1461                  currentData->thread, d->threadData->thread, targetData->thread);
1462
1463 #ifdef Q_WS_MAC
1464         qWarning("On Mac OS X, you might be loading two sets of Qt binaries into the same process. "
1465                  "Check that all plugins are compiled against the right Qt binaries. Export "
1466                  "DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.");
1467 #endif
1468
1469         return;
1470     }
1471
1472     // prepare to move
1473     d->moveToThread_helper();
1474
1475     QOrderedMutexLocker locker(&currentData->postEventList.mutex,
1476                                &targetData->postEventList.mutex);
1477
1478     // keep currentData alive (since we've got it locked)
1479     currentData->ref();
1480
1481     // move the object
1482     d_func()->setThreadData_helper(currentData, targetData);
1483
1484     locker.unlock();
1485
1486     // now currentData can commit suicide if it wants to
1487     currentData->deref();
1488 }
1489
1490 void QObjectPrivate::moveToThread_helper()
1491 {
1492     Q_Q(QObject);
1493     QEvent e(QEvent::ThreadChange);
1494     QCoreApplication::sendEvent(q, &e);
1495     for (int i = 0; i < children.size(); ++i) {
1496         QObject *child = children.at(i);
1497         child->d_func()->moveToThread_helper();
1498     }
1499 }
1500
1501 void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData)
1502 {
1503     Q_Q(QObject);
1504
1505     // move posted events
1506     int eventsMoved = 0;
1507     for (int i = 0; i < currentData->postEventList.size(); ++i) {
1508         const QPostEvent &pe = currentData->postEventList.at(i);
1509         if (!pe.event)
1510             continue;
1511         if (pe.receiver == q) {
1512             // move this post event to the targetList
1513             targetData->postEventList.addEvent(pe);
1514             const_cast<QPostEvent &>(pe).event = 0;
1515             ++eventsMoved;
1516         }
1517     }
1518     if (eventsMoved > 0 && targetData->eventDispatcher) {
1519         targetData->canWait = false;
1520         targetData->eventDispatcher->wakeUp();
1521     }
1522
1523     // the current emitting thread shouldn't restore currentSender after calling moveToThread()
1524     if (currentSender)
1525         currentSender->ref = 0;
1526     currentSender = 0;
1527
1528 #ifdef QT_JAMBI_BUILD
1529     // the current event thread also shouldn't restore the delete watch
1530     inEventHandler = false;
1531
1532     if (deleteWatch)
1533         *deleteWatch = 1;
1534     deleteWatch = 0;
1535 #endif
1536
1537     // set new thread data
1538     targetData->ref();
1539     threadData->deref();
1540     threadData = targetData;
1541
1542     for (int i = 0; i < children.size(); ++i) {
1543         QObject *child = children.at(i);
1544         child->d_func()->setThreadData_helper(currentData, targetData);
1545     }
1546 }
1547
1548 void QObjectPrivate::_q_reregisterTimers(void *pointer)
1549 {
1550     Q_Q(QObject);
1551     QList<QPair<int, int> > *timerList = reinterpret_cast<QList<QPair<int, int> > *>(pointer);
1552     QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
1553     for (int i = 0; i < timerList->size(); ++i) {
1554         const QPair<int, int> &pair = timerList->at(i);
1555         eventDispatcher->registerTimer(pair.first, pair.second, q);
1556     }
1557     delete timerList;
1558 }
1559
1560
1561 //
1562 // The timer flag hasTimer is set when startTimer is called.
1563 // It is not reset when killing the timer because more than
1564 // one timer might be active.
1565 //
1566
1567 /*!
1568     Starts a timer and returns a timer identifier, or returns zero if
1569     it could not start a timer.
1570
1571     A timer event will occur every \a interval milliseconds until
1572     killTimer() is called. If \a interval is 0, then the timer event
1573     occurs once every time there are no more window system events to
1574     process.
1575
1576     The virtual timerEvent() function is called with the QTimerEvent
1577     event parameter class when a timer event occurs. Reimplement this
1578     function to get timer events.
1579
1580     If multiple timers are running, the QTimerEvent::timerId() can be
1581     used to find out which timer was activated.
1582
1583     Example:
1584
1585     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 8
1586
1587     Note that QTimer's accuracy depends on the underlying operating
1588     system and hardware. Most platforms support an accuracy of 20
1589     milliseconds; some provide more. If Qt is unable to deliver the
1590     requested number of timer events, it will silently discard some.
1591
1592     The QTimer class provides a high-level programming interface with
1593     single-shot timers and timer signals instead of events. There is
1594     also a QBasicTimer class that is more lightweight than QTimer and
1595     less clumsy than using timer IDs directly.
1596
1597     \sa timerEvent(), killTimer(), QTimer::singleShot()
1598 */
1599
1600 int QObject::startTimer(int interval)
1601 {
1602     Q_D(QObject);
1603
1604     if (interval < 0) {
1605         qWarning("QObject::startTimer: QTimer cannot have a negative interval");
1606         return 0;
1607     }
1608
1609     d->pendTimer = true;                                // set timer flag
1610
1611     if (!d->threadData->eventDispatcher) {
1612         qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
1613         return 0;
1614     }
1615     return d->threadData->eventDispatcher->registerTimer(interval, this);
1616 }
1617
1618 /*!
1619     Kills the timer with timer identifier, \a id.
1620
1621     The timer identifier is returned by startTimer() when a timer
1622     event is started.
1623
1624     \sa timerEvent(), startTimer()
1625 */
1626
1627 void QObject::killTimer(int id)
1628 {
1629     Q_D(QObject);
1630     if (d->threadData->eventDispatcher)
1631         d->threadData->eventDispatcher->unregisterTimer(id);
1632 }
1633
1634
1635 /*!
1636     \fn QObject *QObject::parent() const
1637
1638     Returns a pointer to the parent object.
1639
1640     \sa children()
1641 */
1642
1643 /*!
1644     \fn const QObjectList &QObject::children() const
1645
1646     Returns a list of child objects.
1647     The QObjectList class is defined in the \c{<QObject>} header
1648     file as the following:
1649
1650     \quotefromfile src/corelib/kernel/qobject.h
1651     \skipto /typedef .*QObjectList/
1652     \printuntil QObjectList
1653
1654     The first child added is the \l{QList::first()}{first} object in
1655     the list and the last child added is the \l{QList::last()}{last}
1656     object in the list, i.e. new children are appended at the end.
1657
1658     Note that the list order changes when QWidget children are
1659     \l{QWidget::raise()}{raised} or \l{QWidget::lower()}{lowered}. A
1660     widget that is raised becomes the last object in the list, and a
1661     widget that is lowered becomes the first object in the list.
1662
1663     \sa findChild(), findChildren(), parent(), setParent()
1664 */
1665
1666 #ifdef QT3_SUPPORT
1667 static void objSearch(QObjectList &result,
1668                       const QObjectList &list,
1669                       const char *inheritsClass,
1670                       bool onlyWidgets,
1671                       const char *objName,
1672                       QRegExp *rx,
1673                       bool recurse)
1674 {
1675     for (int i = 0; i < list.size(); ++i) {
1676         QObject *obj = list.at(i);
1677         if (!obj)
1678             continue;
1679         bool ok = true;
1680         if (onlyWidgets)
1681             ok = obj->isWidgetType();
1682         else if (inheritsClass && !obj->inherits(inheritsClass))
1683             ok = false;
1684         if (ok) {
1685             if (objName)
1686                 ok = (obj->objectName() == QLatin1String(objName));
1687 #ifndef QT_NO_REGEXP
1688             else if (rx)
1689                 ok = (rx->indexIn(obj->objectName()) != -1);
1690 #endif
1691         }
1692         if (ok)                                // match!
1693             result.append(obj);
1694         if (recurse) {
1695             QObjectList clist = obj->children();
1696             if (!clist.isEmpty())
1697                 objSearch(result, clist, inheritsClass,
1698                            onlyWidgets, objName, rx, recurse);
1699         }
1700     }
1701 }
1702
1703 /*!
1704     \internal
1705
1706     Searches the children and optionally grandchildren of this object,
1707     and returns a list of those objects that are named or that match
1708     \a objName and inherit \a inheritsClass. If \a inheritsClass is 0
1709     (the default), all classes match. If \a objName is 0 (the
1710     default), all object names match.
1711
1712     If \a regexpMatch is true (the default), \a objName is a regular
1713     expression that the objects's names must match. The syntax is that
1714     of a QRegExp. If \a regexpMatch is false, \a objName is a string
1715     and object names must match it exactly.
1716
1717     Note that \a inheritsClass uses single inheritance from QObject,
1718     the way inherits() does. According to inherits(), QWidget
1719     inherits QObject but not QPaintDevice. This does not quite match
1720     reality, but is the best that can be done on the wide variety of
1721     compilers Qt supports.
1722
1723     Finally, if \a recursiveSearch is true (the default), queryList()
1724     searches \e{n}th-generation as well as first-generation children.
1725
1726     If all this seems a bit complex for your needs, the simpler
1727     child() function may be what you want.
1728
1729     This somewhat contrived example disables all the buttons in this
1730     window:
1731
1732     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 9
1733
1734     \warning Delete the list as soon you have finished using it. The
1735     list contains pointers that may become invalid at almost any time
1736     without notice (as soon as the user closes a window you may have
1737     dangling pointers, for example).
1738
1739     \sa child() children(), parent(), inherits(), objectName(), QRegExp
1740 */
1741
1742 QObjectList QObject::queryList(const char *inheritsClass,
1743                                const char *objName,
1744                                bool regexpMatch,
1745                                bool recursiveSearch) const
1746 {
1747     Q_D(const QObject);
1748     QObjectList list;
1749     bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
1750 #ifndef QT_NO_REGEXP
1751     if (regexpMatch && objName) {                // regexp matching
1752         QRegExp rx(QString::fromLatin1(objName));
1753         objSearch(list, d->children, inheritsClass, onlyWidgets, 0, &rx, recursiveSearch);
1754     } else
1755 #endif
1756     {
1757         objSearch(list, d->children, inheritsClass, onlyWidgets, objName, 0, recursiveSearch);
1758     }
1759     return list;
1760 }
1761 #endif
1762
1763 /*!
1764     \fn T *QObject::findChild(const QString &name) const
1765
1766     Returns the child of this object that can be cast into type T and
1767     that is called \a name, or 0 if there is no such object.
1768     Omitting the \a name argument causes all object names to be matched.
1769     The search is performed recursively.
1770
1771     If there is more than one child matching the search, the most
1772     direct ancestor is returned. If there are several direct
1773     ancestors, it is undefined which one will be returned. In that
1774     case, findChildren() should be used.
1775
1776     This example returns a child \l{QPushButton} of \c{parentWidget}
1777     named \c{"button1"}:
1778
1779     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 10
1780
1781     This example returns a \l{QListWidget} child of \c{parentWidget}:
1782
1783     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11
1784
1785     \sa findChildren()
1786 */
1787
1788 /*!
1789     \fn QList<T> QObject::findChildren(const QString &name) const
1790
1791     Returns all children of this object with the given \a name that can be
1792     cast to type T, or an empty list if there are no such objects.
1793     Omitting the \a name argument causes all object names to be matched.
1794     The search is performed recursively.
1795
1796     The following example shows how to find a list of child \l{QWidget}s of
1797     the specified \c{parentWidget} named \c{widgetname}:
1798
1799     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 12
1800
1801     This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
1802
1803     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13
1804
1805     \sa findChild()
1806 */
1807
1808 /*!
1809     \fn QList<T> QObject::findChildren(const QRegExp &regExp) const
1810     \overload findChildren()
1811
1812     Returns the children of this object that can be cast to type T
1813     and that have names matching the regular expression \a regExp,
1814     or an empty list if there are no such objects.
1815     The search is performed recursively.
1816 */
1817
1818 /*!
1819     \fn T qFindChild(const QObject *obj, const QString &name)
1820     \relates QObject
1821     \overload qFindChildren()
1822     \obsolete
1823
1824     This function is equivalent to
1825     \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
1826
1827     \note This function was provided as a workaround for MSVC 6
1828     which did not support member template functions. It is advised
1829     to use the other form in new code.
1830
1831     \sa QObject::findChild()
1832 */
1833
1834 /*!
1835     \fn QList<T> qFindChildren(const QObject *obj, const QString &name)
1836     \relates QObject
1837     \overload qFindChildren()
1838     \obsolete
1839
1840     This function is equivalent to
1841     \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
1842
1843     \note This function was provided as a workaround for MSVC 6
1844     which did not support member template functions. It is advised
1845     to use the other form in new code.
1846
1847     \sa QObject::findChildren()
1848 */
1849
1850 /*!
1851     \fn QList<T> qFindChildren(const QObject *obj, const QRegExp &regExp)
1852     \relates QObject
1853     \overload qFindChildren()
1854
1855     This function is equivalent to
1856     \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp).
1857
1858     \note This function was provided as a workaround for MSVC 6
1859     which did not support member template functions. It is advised
1860     to use the other form in new code.
1861
1862     \sa QObject::findChildren()
1863 */
1864
1865 /*!
1866     \internal
1867 */
1868 void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
1869                              const QMetaObject &mo, QList<void*> *list)
1870 {
1871     if (!parent || !list)
1872         return;
1873     const QObjectList &children = parent->children();
1874     QObject *obj;
1875     for (int i = 0; i < children.size(); ++i) {
1876         obj = children.at(i);
1877         if (mo.cast(obj)) {
1878             if (re) {
1879                 if (re->indexIn(obj->objectName()) != -1)
1880                     list->append(obj);
1881             } else {
1882                 if (name.isNull() || obj->objectName() == name)
1883                     list->append(obj);
1884             }
1885         }
1886         qt_qFindChildren_helper(obj, name, re, mo, list);
1887     }
1888 }
1889
1890 /*! \internal
1891  */
1892 QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo)
1893 {
1894     if (!parent)
1895         return 0;
1896     const QObjectList &children = parent->children();
1897     QObject *obj;
1898     int i;
1899     for (i = 0; i < children.size(); ++i) {
1900         obj = children.at(i);
1901         if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
1902             return obj;
1903     }
1904     for (i = 0; i < children.size(); ++i) {
1905         obj = qt_qFindChild_helper(children.at(i), name, mo);
1906         if (obj)
1907             return obj;
1908     }
1909     return 0;
1910 }
1911
1912 /*!
1913     Makes the object a child of \a parent.
1914
1915     \sa QWidget::setParent()
1916 */
1917
1918 void QObject::setParent(QObject *parent)
1919 {
1920     Q_D(QObject);
1921     Q_ASSERT(!d->isWidget);
1922     d->setParent_helper(parent);
1923 }
1924
1925 void QObjectPrivate::deleteChildren()
1926 {
1927     const bool reallyWasDeleted = wasDeleted;
1928     wasDeleted = true;
1929     // delete children objects
1930     // don't use qDeleteAll as the destructor of the child might
1931     // delete siblings
1932     for (int i = 0; i < children.count(); ++i) {
1933         currentChildBeingDeleted = children.at(i);
1934         children[i] = 0;
1935         delete currentChildBeingDeleted;
1936     }
1937     children.clear();
1938     currentChildBeingDeleted = 0;
1939     wasDeleted = reallyWasDeleted;
1940 }
1941
1942 void QObjectPrivate::setParent_helper(QObject *o)
1943 {
1944     Q_Q(QObject);
1945     if (o == parent)
1946         return;
1947     if (parent) {
1948         QObjectPrivate *parentD = parent->d_func();
1949         if (parentD->wasDeleted && wasDeleted
1950             && parentD->currentChildBeingDeleted == q) {
1951             // don't do anything since QObjectPrivate::deleteChildren() already
1952             // cleared our entry in parentD->children.
1953         } else {
1954             const int index = parentD->children.indexOf(q);
1955             if (parentD->wasDeleted) {
1956                 parentD->children[index] = 0;
1957             } else {
1958                 parentD->children.removeAt(index);
1959                 if (sendChildEvents && parentD->receiveChildEvents) {
1960                     QChildEvent e(QEvent::ChildRemoved, q);
1961                     QCoreApplication::sendEvent(parent, &e);
1962                 }
1963             }
1964         }
1965     }
1966     parent = o;
1967     if (parent) {
1968         // object hierarchies are constrained to a single thread
1969         if (threadData != parent->d_func()->threadData) {
1970             qWarning("QObject::setParent: Cannot set parent, new parent is in a different thread");
1971             parent = 0;
1972             return;
1973         }
1974         parent->d_func()->children.append(q);
1975         if(sendChildEvents && parent->d_func()->receiveChildEvents) {
1976             if (!isWidget) {
1977                 QChildEvent e(QEvent::ChildAdded, q);
1978                 QCoreApplication::sendEvent(parent, &e);
1979 #ifdef QT3_SUPPORT
1980                 if (QCoreApplicationPrivate::useQt3Support) {
1981                     if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) {
1982                         QCoreApplication::postEvent(parent,
1983                                                     new QEvent(QEvent::ChildInsertedRequest),
1984                                                     Qt::HighEventPriority);
1985                     }
1986                     parent->d_func()->pendingChildInsertedEvents.append(q);
1987                 }
1988 #endif
1989             }
1990         }
1991     }
1992     if (!wasDeleted && declarativeData)
1993         QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
1994 }
1995
1996 /*!
1997     \fn void QObject::installEventFilter(QObject *filterObj)
1998
1999     Installs an event filter \a filterObj on this object. For example:
2000     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 14
2001
2002     An event filter is an object that receives all events that are
2003     sent to this object. The filter can either stop the event or
2004     forward it to this object. The event filter \a filterObj receives
2005     events via its eventFilter() function. The eventFilter() function
2006     must return true if the event should be filtered, (i.e. stopped);
2007     otherwise it must return false.
2008
2009     If multiple event filters are installed on a single object, the
2010     filter that was installed last is activated first.
2011
2012     Here's a \c KeyPressEater class that eats the key presses of its
2013     monitored objects:
2014
2015     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 15
2016
2017     And here's how to install it on two widgets:
2018
2019     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 16
2020
2021     The QShortcut class, for example, uses this technique to intercept
2022     shortcut key presses.
2023
2024     \warning If you delete the receiver object in your eventFilter()
2025     function, be sure to return true. If you return false, Qt sends
2026     the event to the deleted object and the program will crash.
2027
2028     Note that the filtering object must be in the same thread as this
2029     object. If \a filterObj is in a different thread, this function does
2030     nothing. If either \a filterObj or this object are moved to a different
2031     thread after calling this function, the event filter will not be
2032     called until both objects have the same thread affinity again (it
2033     is \e not removed).
2034
2035     \sa removeEventFilter(), eventFilter(), event()
2036 */
2037
2038 void QObject::installEventFilter(QObject *obj)
2039 {
2040     Q_D(QObject);
2041     if (!obj)
2042         return;
2043     if (d->threadData != obj->d_func()->threadData) {
2044         qWarning("QObject::installEventFilter(): Cannot filter events for objects in a different thread.");
2045         return;
2046     }
2047
2048     // clean up unused items in the list
2049     d->eventFilters.removeAll((QObject*)0);
2050     d->eventFilters.removeAll(obj);
2051     d->eventFilters.prepend(obj);
2052 }
2053
2054 /*!
2055     Removes an event filter object \a obj from this object. The
2056     request is ignored if such an event filter has not been installed.
2057
2058     All event filters for this object are automatically removed when
2059     this object is destroyed.
2060
2061     It is always safe to remove an event filter, even during event
2062     filter activation (i.e. from the eventFilter() function).
2063
2064     \sa installEventFilter(), eventFilter(), event()
2065 */
2066
2067 void QObject::removeEventFilter(QObject *obj)
2068 {
2069     Q_D(QObject);
2070     for (int i = 0; i < d->eventFilters.count(); ++i) {
2071         if (d->eventFilters.at(i) == obj)
2072             d->eventFilters[i] = 0;
2073     }
2074 }
2075
2076
2077 /*!
2078     \fn QObject::destroyed(QObject *obj)
2079
2080     This signal is emitted immediately before the object \a obj is
2081     destroyed, and can not be blocked.
2082
2083     All the objects's children are destroyed immediately after this
2084     signal is emitted.
2085
2086     \sa deleteLater(), QPointer
2087 */
2088
2089 /*!
2090     Schedules this object for deletion.
2091
2092     The object will be deleted when control returns to the event
2093     loop. If the event loop is not running when this function is
2094     called (e.g. deleteLater() is called on an object before
2095     QCoreApplication::exec()), the object will be deleted once the
2096     event loop is started. If deleteLater() is called after the main event loop
2097     has stopped, the object will not be deleted.
2098     Since Qt 4.8, if deleteLater() is called on an object that lives in a
2099     thread with no running event loop, the object will be destroyed when the
2100     thread finishes.
2101
2102     Note that entering and leaving a new event loop (e.g., by opening a modal
2103     dialog) will \e not perform the deferred deletion; for the object to be
2104     deleted, the control must return to the event loop from which
2105     deleteLater() was called.
2106
2107     \bold{Note:} It is safe to call this function more than once; when the
2108     first deferred deletion event is delivered, any pending events for the
2109     object are removed from the event queue.
2110
2111     \sa destroyed(), QPointer
2112 */
2113 void QObject::deleteLater()
2114 {
2115     QCoreApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));
2116 }
2117
2118 /*!
2119     \fn QString QObject::tr(const char *sourceText, const char *disambiguation, int n)
2120     \reentrant
2121
2122     Returns a translated version of \a sourceText, optionally based on a
2123     \a disambiguation string and value of \a n for strings containing plurals;
2124     otherwise returns \a sourceText itself if no appropriate translated string
2125     is available.
2126
2127     Example:
2128     \snippet mainwindows/sdi/mainwindow.cpp implicit tr context
2129     \dots
2130
2131     If the same \a sourceText is used in different roles within the
2132     same context, an additional identifying string may be passed in
2133     \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
2134     the preferred way to pass comments to translators.
2135
2136     Example:
2137
2138     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
2139     \dots
2140
2141     See \l{Writing Source Code for Translation} for a detailed description of
2142     Qt's translation mechanisms in general, and the
2143     \l{Writing Source Code for Translation#Disambiguation}{Disambiguation}
2144     section for information on disambiguation.
2145
2146     \warning This method is reentrant only if all translators are
2147     installed \e before calling this method. Installing or removing
2148     translators while performing translations is not supported. Doing
2149     so will probably result in crashes or other undesirable behavior.
2150
2151     \sa trUtf8(), QApplication::translate(), QTextCodec::setCodecForTr(), {Internationalization with Qt}
2152 */
2153
2154 /*!
2155     \fn QString QObject::trUtf8(const char *sourceText, const char *disambiguation, int n)
2156     \reentrant
2157
2158     Returns a translated version of \a sourceText, or
2159     QString::fromUtf8(\a sourceText) if there is no appropriate
2160     version. It is otherwise identical to tr(\a sourceText, \a
2161     disambiguation, \a n).
2162
2163     Note that using the Utf8 variants of the translation functions
2164     is not required if \c CODECFORTR is already set to UTF-8 in the
2165     qmake project file and QTextCodec::setCodecForTr("UTF-8") is
2166     used.
2167
2168     \warning This method is reentrant only if all translators are
2169     installed \e before calling this method. Installing or removing
2170     translators while performing translations is not supported. Doing
2171     so will probably result in crashes or other undesirable behavior.
2172
2173     \warning For portability reasons, we recommend that you use
2174     escape sequences for specifying non-ASCII characters in string
2175     literals to trUtf8(). For example:
2176
2177     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 20
2178
2179     \sa tr(), QApplication::translate(), {Internationalization with Qt}
2180 */
2181
2182
2183
2184
2185 /*****************************************************************************
2186   Signals and slots
2187  *****************************************************************************/
2188
2189
2190 const char *qFlagLocation(const char *method)
2191 {
2192     QThreadData::current()->flaggedSignatures.store(method);
2193     return method;
2194 }
2195
2196 static int extract_code(const char *member)
2197 {
2198     // extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE
2199     return (((int)(*member) - '0') & 0x3);
2200 }
2201
2202 static const char * extract_location(const char *member)
2203 {
2204     if (QThreadData::current()->flaggedSignatures.contains(member)) {
2205         // signature includes location information after the first null-terminator
2206         const char *location = member + qstrlen(member) + 1;
2207         if (*location != '\0')
2208             return location;
2209     }
2210     return 0;
2211 }
2212
2213 static bool check_signal_macro(const QObject *sender, const char *signal,
2214                                 const char *func, const char *op)
2215 {
2216     int sigcode = extract_code(signal);
2217     if (sigcode != QSIGNAL_CODE) {
2218         if (sigcode == QSLOT_CODE)
2219             qWarning("Object::%s: Attempt to %s non-signal %s::%s",
2220                      func, op, sender->metaObject()->className(), signal+1);
2221         else
2222             qWarning("Object::%s: Use the SIGNAL macro to %s %s::%s",
2223                      func, op, sender->metaObject()->className(), signal);
2224         return false;
2225     }
2226     return true;
2227 }
2228
2229 static bool check_method_code(int code, const QObject *object,
2230                                const char *method, const char *func)
2231 {
2232     if (code != QSLOT_CODE && code != QSIGNAL_CODE) {
2233         qWarning("Object::%s: Use the SLOT or SIGNAL macro to "
2234                  "%s %s::%s", func, func, object->metaObject()->className(), method);
2235         return false;
2236     }
2237     return true;
2238 }
2239
2240 static void err_method_notfound(const QObject *object,
2241                                 const char *method, const char *func)
2242 {
2243     const char *type = "method";
2244     switch (extract_code(method)) {
2245         case QSLOT_CODE:   type = "slot";   break;
2246         case QSIGNAL_CODE: type = "signal"; break;
2247     }
2248     const char *loc = extract_location(method);
2249     if (strchr(method,')') == 0)                // common typing mistake
2250         qWarning("Object::%s: Parentheses expected, %s %s::%s%s%s",
2251                  func, type, object->metaObject()->className(), method+1,
2252                  loc ? " in ": "", loc ? loc : "");
2253     else
2254         qWarning("Object::%s: No such %s %s::%s%s%s",
2255                  func, type, object->metaObject()->className(), method+1,
2256                  loc ? " in ": "", loc ? loc : "");
2257
2258 }
2259
2260
2261 static void err_info_about_objects(const char * func,
2262                                     const QObject * sender,
2263                                     const QObject * receiver)
2264 {
2265     QString a = sender ? sender->objectName() : QString();
2266     QString b = receiver ? receiver->objectName() : QString();
2267     if (!a.isEmpty())
2268         qWarning("Object::%s:  (sender name:   '%s')", func, a.toLocal8Bit().data());
2269     if (!b.isEmpty())
2270         qWarning("Object::%s:  (receiver name: '%s')", func, b.toLocal8Bit().data());
2271 }
2272
2273 /*!
2274     Returns a pointer to the object that sent the signal, if called in
2275     a slot activated by a signal; otherwise it returns 0. The pointer
2276     is valid only during the execution of the slot that calls this
2277     function from this object's thread context.
2278
2279     The pointer returned by this function becomes invalid if the
2280     sender is destroyed, or if the slot is disconnected from the
2281     sender's signal.
2282
2283     \warning This function violates the object-oriented principle of
2284     modularity. However, getting access to the sender might be useful
2285     when many signals are connected to a single slot.
2286
2287     \warning As mentioned above, the return value of this function is
2288     not valid when the slot is called via a Qt::DirectConnection from
2289     a thread different from this object's thread. Do not use this
2290     function in this type of scenario.
2291
2292     \sa senderSignalIndex(), QSignalMapper
2293 */
2294
2295 QObject *QObject::sender() const
2296 {
2297     Q_D(const QObject);
2298
2299     QMutexLocker locker(signalSlotLock(this));
2300     if (!d->currentSender)
2301         return 0;
2302
2303     for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
2304         if (c->sender == d->currentSender->sender)
2305             return d->currentSender->sender;
2306     }
2307
2308     return 0;
2309 }
2310
2311 /*!
2312     \since 4.8
2313
2314     Returns the meta-method index of the signal that called the currently
2315     executing slot, which is a member of the class returned by sender().
2316     If called outside of a slot activated by a signal, -1 is returned.
2317
2318     For signals with default parameters, this function will always return
2319     the index with all parameters, regardless of which was used with
2320     connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
2321     will have two different indexes (with and without the parameter), but
2322     this function will always return the index with a parameter. This does
2323     not apply when overloading signals with different parameters.
2324
2325     \warning This function violates the object-oriented principle of
2326     modularity. However, getting access to the signal index might be useful
2327     when many signals are connected to a single slot.
2328
2329     \warning The return value of this function is not valid when the slot
2330     is called via a Qt::DirectConnection from a thread different from this
2331     object's thread. Do not use this function in this type of scenario.
2332
2333     \sa sender(), QMetaObject::indexOfSignal(), QMetaObject::method()
2334 */
2335
2336 int QObject::senderSignalIndex() const
2337 {
2338     Q_D(const QObject);
2339
2340     QMutexLocker locker(signalSlotLock(this));
2341     if (!d->currentSender)
2342         return -1;
2343
2344     for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
2345         if (c->sender == d->currentSender->sender)
2346             return d->currentSender->signal;
2347     }
2348
2349     return -1;
2350 }
2351
2352 /*!
2353     Returns the number of receivers connected to the \a signal.
2354
2355     Since both slots and signals can be used as receivers for signals,
2356     and the same connections can be made many times, the number of
2357     receivers is the same as the number of connections made from this
2358     signal.
2359
2360     When calling this function, you can use the \c SIGNAL() macro to
2361     pass a specific signal:
2362
2363     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 21
2364
2365     As the code snippet above illustrates, you can use this function
2366     to avoid emitting a signal that nobody listens to.
2367
2368     \warning This function violates the object-oriented principle of
2369     modularity. However, it might be useful when you need to perform
2370     expensive initialization only if something is connected to a
2371     signal.
2372 */
2373
2374 int QObject::receivers(const char *signal) const
2375 {
2376     Q_D(const QObject);
2377     int receivers = 0;
2378     if (signal) {
2379         QByteArray signal_name = QMetaObject::normalizedSignature(signal);
2380         signal = signal_name;
2381 #ifndef QT_NO_DEBUG
2382         if (!check_signal_macro(this, signal, "receivers", "bind"))
2383             return 0;
2384 #endif
2385         signal++; // skip code
2386         int signal_index = d->signalIndex(signal);
2387         if (signal_index < 0) {
2388 #ifndef QT_NO_DEBUG
2389             err_method_notfound(this, signal-1, "receivers");
2390 #endif
2391             return false;
2392         }
2393
2394         Q_D(const QObject);
2395         QMutexLocker locker(signalSlotLock(this));
2396         if (d->connectionLists) {
2397             if (signal_index < d->connectionLists->count()) {
2398                 const QObjectPrivate::Connection *c =
2399                     d->connectionLists->at(signal_index).first;
2400                 while (c) {
2401                     receivers += c->receiver ? 1 : 0;
2402                     c = c->nextConnectionList;
2403                 }
2404             }
2405         }
2406     }
2407     return receivers;
2408 }
2409
2410 /*!
2411     \internal
2412
2413     This helper function calculates signal and method index for the given
2414     member in the specified class.
2415
2416     \list
2417     \o If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
2418
2419     \o If specified member is not a member of obj instance class (or one of
2420     its parent classes) then both signalIndex and methodIndex are set to -1.
2421     \endlist
2422
2423     This function is used by QObject::connect and QObject::disconnect which
2424     are working with QMetaMethod.
2425
2426     \a signalIndex is set to the signal index of member. If the member
2427     specified is not signal this variable is set to -1.
2428
2429     \a methodIndex is set to the method index of the member. If the
2430     member is not a method of the object specified by the \a obj argument this
2431     variable is set to -1.
2432 */
2433 void QMetaObjectPrivate::memberIndexes(const QObject *obj,
2434                                        const QMetaMethod &member,
2435                                        int *signalIndex, int *methodIndex)
2436 {
2437     *signalIndex = -1;
2438     *methodIndex = -1;
2439     if (!obj || !member.mobj)
2440         return;
2441     const QMetaObject *m = obj->metaObject();
2442     // Check that member is member of obj class
2443     while (m != 0 && m != member.mobj)
2444         m = m->d.superdata;
2445     if (!m)
2446         return;
2447     *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
2448
2449     int signalOffset;
2450     int methodOffset;
2451     computeOffsets(m, &signalOffset, &methodOffset);
2452
2453     *methodIndex += methodOffset;
2454     if (member.methodType() == QMetaMethod::Signal) {
2455         *signalIndex = originalClone(m, *signalIndex);
2456         *signalIndex += signalOffset;
2457     } else {
2458         *signalIndex = -1;
2459     }
2460 }
2461
2462 static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
2463                                          const QMetaObject *receiver, const QMetaMethod &method)
2464 {
2465     if (signal.attributes() & QMetaMethod::Compatibility) {
2466         if (!(method.attributes() & QMetaMethod::Compatibility))
2467             qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
2468                      sender->className(), signal.signature());
2469     } else if ((method.attributes() & QMetaMethod::Compatibility) &&
2470                method.methodType() == QMetaMethod::Signal) {
2471         qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
2472                  sender->className(), signal.signature(),
2473                  receiver->className(), method.signature());
2474     }
2475 }
2476
2477 /*!
2478     \threadsafe
2479
2480     Creates a connection of the given \a type from the \a signal in
2481     the \a sender object to the \a method in the \a receiver object.
2482     Returns true if the connection succeeds; otherwise returns false.
2483
2484     You must use the \c SIGNAL() and \c SLOT() macros when specifying
2485     the \a signal and the \a method, for example:
2486
2487     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 22
2488
2489     This example ensures that the label always displays the current
2490     scroll bar value. Note that the signal and slots parameters must not
2491     contain any variable names, only the type. E.g. the following would
2492     not work and return false:
2493
2494     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 23
2495
2496     A signal can also be connected to another signal:
2497
2498     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 24
2499
2500     In this example, the \c MyWidget constructor relays a signal from
2501     a private member variable, and makes it available under a name
2502     that relates to \c MyWidget.
2503
2504     A signal can be connected to many slots and signals. Many signals
2505     can be connected to one slot.
2506
2507     If a signal is connected to several slots, the slots are activated
2508     in the same order as the order the connection was made, when the
2509     signal is emitted.
2510
2511     The function returns true if it successfully connects the signal
2512     to the slot. It will return false if it cannot create the
2513     connection, for example, if QObject is unable to verify the
2514     existence of either \a signal or \a method, or if their signatures
2515     aren't compatible.
2516
2517     By default, a signal is emitted for every connection you make;
2518     two signals are emitted for duplicate connections. You can break
2519     all of these connections with a single disconnect() call.
2520     If you pass the Qt::UniqueConnection \a type, the connection will only
2521     be made if it is not a duplicate. If there is already a duplicate
2522     (exact same signal to the exact same slot on the same objects),
2523     the connection will fail and connect will return false.
2524
2525     The optional \a type parameter describes the type of connection
2526     to establish. In particular, it determines whether a particular
2527     signal is delivered to a slot immediately or queued for delivery
2528     at a later time. If the signal is queued, the parameters must be
2529     of types that are known to Qt's meta-object system, because Qt
2530     needs to copy the arguments to store them in an event behind the
2531     scenes. If you try to use a queued connection and get the error
2532     message
2533
2534     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 25
2535
2536     call qRegisterMetaType() to register the data type before you
2537     establish the connection.
2538
2539     \sa disconnect(), sender(), qRegisterMetaType(), Q_DECLARE_METATYPE()
2540 */
2541
2542 bool QObject::connect(const QObject *sender, const char *signal,
2543                       const QObject *receiver, const char *method,
2544                       Qt::ConnectionType type)
2545 {
2546     {
2547         const void *cbdata[] = { sender, signal, receiver, method, &type };
2548         if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
2549             return true;
2550     }
2551
2552 #ifndef QT_NO_DEBUG
2553     bool warnCompat = true;
2554 #endif
2555     if (type == Qt::AutoCompatConnection) {
2556         type = Qt::AutoConnection;
2557 #ifndef QT_NO_DEBUG
2558         warnCompat = false;
2559 #endif
2560     }
2561
2562     if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
2563         qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2564                  sender ? sender->metaObject()->className() : "(null)",
2565                  (signal && *signal) ? signal+1 : "(null)",
2566                  receiver ? receiver->metaObject()->className() : "(null)",
2567                  (method && *method) ? method+1 : "(null)");
2568         return false;
2569     }
2570     QByteArray tmp_signal_name;
2571
2572     if (!check_signal_macro(sender, signal, "connect", "bind"))
2573         return false;
2574     const QMetaObject *smeta = sender->metaObject();
2575     const char *signal_arg = signal;
2576     ++signal; //skip code
2577     int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
2578     if (signal_index < 0) {
2579         // check for normalized signatures
2580         tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
2581         signal = tmp_signal_name.constData() + 1;
2582
2583         smeta = sender->metaObject();
2584         signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
2585     }
2586     if (signal_index < 0) {
2587         // re-use tmp_signal_name and signal from above
2588
2589         smeta = sender->metaObject();
2590         signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
2591     }
2592     if (signal_index < 0) {
2593         err_method_notfound(sender, signal_arg, "connect");
2594         err_info_about_objects("connect", sender, receiver);
2595         return false;
2596     }
2597     signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2598     int signalOffset, methodOffset;
2599     computeOffsets(smeta, &signalOffset, &methodOffset);
2600     int signal_absolute_index = signal_index + methodOffset;
2601     signal_index += signalOffset;
2602
2603     QByteArray tmp_method_name;
2604     int membcode = extract_code(method);
2605
2606     if (!check_method_code(membcode, receiver, method, "connect"))
2607         return false;
2608     const char *method_arg = method;
2609     ++method; // skip code
2610
2611     const QMetaObject *rmeta = receiver->metaObject();
2612     int method_index_relative = -1;
2613     switch (membcode) {
2614     case QSLOT_CODE:
2615         method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
2616         break;
2617     case QSIGNAL_CODE:
2618         method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
2619         break;
2620     }
2621
2622     if (method_index_relative < 0) {
2623         // check for normalized methods
2624         tmp_method_name = QMetaObject::normalizedSignature(method);
2625         method = tmp_method_name.constData();
2626
2627         // rmeta may have been modified above
2628         rmeta = receiver->metaObject();
2629         switch (membcode) {
2630         case QSLOT_CODE:
2631             method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
2632             if (method_index_relative < 0)
2633                 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, true);
2634             break;
2635         case QSIGNAL_CODE:
2636             method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
2637             if (method_index_relative < 0)
2638                 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, true);
2639             break;
2640         }
2641     }
2642
2643     if (method_index_relative < 0) {
2644         err_method_notfound(receiver, method_arg, "connect");
2645         err_info_about_objects("connect", sender, receiver);
2646         return false;
2647     }
2648
2649     if (!QMetaObject::checkConnectArgs(signal, method)) {
2650         qWarning("QObject::connect: Incompatible sender/receiver arguments"
2651                  "\n        %s::%s --> %s::%s",
2652                  sender->metaObject()->className(), signal,
2653                  receiver->metaObject()->className(), method);
2654         return false;
2655     }
2656
2657     int *types = 0;
2658     if ((type == Qt::QueuedConnection)
2659             && !(types = queuedConnectionTypes(smeta->method(signal_absolute_index).parameterTypes())))
2660         return false;
2661
2662 #ifndef QT_NO_DEBUG
2663     if (warnCompat) {
2664         QMetaMethod smethod = smeta->method(signal_absolute_index);
2665         QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
2666         check_and_warn_compat(smeta, smethod, rmeta, rmethod);
2667     }
2668 #endif
2669     if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index_relative, rmeta ,type, types))
2670         return false;
2671     const_cast<QObject*>(sender)->connectNotify(signal - 1);
2672     return true;
2673 }
2674
2675 /*!
2676     \since 4.8
2677
2678     Creates a connection of the given \a type from the \a signal in
2679     the \a sender object to the \a method in the \a receiver object.
2680     Returns true if the connection succeeds; otherwise returns false.
2681
2682     This function works in the same way as
2683     connect(const QObject *sender, const char *signal,
2684             const QObject *receiver, const char *method,
2685             Qt::ConnectionType type)
2686     but it uses QMetaMethod to specify signal and method.
2687
2688     \sa connect(const QObject *sender, const char *signal,
2689                 const QObject *receiver, const char *method,
2690                 Qt::ConnectionType type)
2691  */
2692 bool QObject::connect(const QObject *sender, const QMetaMethod &signal,
2693                       const QObject *receiver, const QMetaMethod &method,
2694                       Qt::ConnectionType type)
2695 {
2696 #ifndef QT_NO_DEBUG
2697     bool warnCompat = true;
2698 #endif
2699     if (type == Qt::AutoCompatConnection) {
2700         type = Qt::AutoConnection;
2701 #ifndef QT_NO_DEBUG
2702         warnCompat = false;
2703 #endif
2704     }
2705
2706     if (sender == 0
2707             || receiver == 0
2708             || signal.methodType() != QMetaMethod::Signal
2709             || method.methodType() == QMetaMethod::Constructor) {
2710         qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2711                  sender ? sender->metaObject()->className() : "(null)",
2712                  signal.signature(),
2713                  receiver ? receiver->metaObject()->className() : "(null)",
2714                  method.signature() );
2715         return false;
2716     }
2717
2718     QVarLengthArray<char> signalSignature;
2719     QObjectPrivate::signalSignature(signal, &signalSignature);
2720
2721     {
2722         QByteArray methodSignature;
2723         methodSignature.reserve(qstrlen(method.signature())+1);
2724         methodSignature.append((char)(method.methodType() == QMetaMethod::Slot ? QSLOT_CODE
2725                                     : method.methodType() == QMetaMethod::Signal ? QSIGNAL_CODE : 0  + '0'));
2726         methodSignature.append(method.signature());
2727         const void *cbdata[] = { sender, signalSignature.constData(), receiver, methodSignature.constData(), &type };
2728         if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
2729             return true;
2730     }
2731
2732
2733     int signal_index;
2734     int method_index;
2735     {
2736         int dummy;
2737         QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2738         QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2739     }
2740
2741     const QMetaObject *smeta = sender->metaObject();
2742     const QMetaObject *rmeta = receiver->metaObject();
2743     if (signal_index == -1) {
2744         qWarning("QObject::connect: Can't find signal %s on instance of class %s",
2745                  signal.signature(), smeta->className());
2746         return false;
2747     }
2748     if (method_index == -1) {
2749         qWarning("QObject::connect: Can't find method %s on instance of class %s",
2750                  method.signature(), rmeta->className());
2751         return false;
2752     }
2753     
2754     if (!QMetaObject::checkConnectArgs(signal.signature(), method.signature())) {
2755         qWarning("QObject::connect: Incompatible sender/receiver arguments"
2756                  "\n        %s::%s --> %s::%s",
2757                  smeta->className(), signal.signature(),
2758                  rmeta->className(), method.signature());
2759         return false;
2760     }
2761
2762     int *types = 0;
2763     if ((type == Qt::QueuedConnection)
2764             && !(types = queuedConnectionTypes(signal.parameterTypes())))
2765         return false;
2766
2767 #ifndef QT_NO_DEBUG
2768     if (warnCompat)
2769         check_and_warn_compat(smeta, signal, rmeta, method);
2770 #endif
2771     if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, 0, type, types))
2772         return false;
2773
2774     const_cast<QObject*>(sender)->connectNotify(signalSignature.constData());
2775     return true;
2776 }
2777
2778 /*!
2779     \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
2780     \overload connect()
2781     \threadsafe
2782
2783     Connects \a signal from the \a sender object to this object's \a
2784     method.
2785
2786     Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
2787
2788     Every connection you make emits a signal, so duplicate connections emit
2789     two signals. You can break a connection using disconnect().
2790
2791     \sa disconnect()
2792 */
2793
2794 /*!
2795     \threadsafe
2796
2797     Disconnects \a signal in object \a sender from \a method in object
2798     \a receiver. Returns true if the connection is successfully broken;
2799     otherwise returns false.
2800
2801     A signal-slot connection is removed when either of the objects
2802     involved are destroyed.
2803
2804     disconnect() is typically used in three ways, as the following
2805     examples demonstrate.
2806     \list 1
2807     \i Disconnect everything connected to an object's signals:
2808
2809        \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
2810
2811        equivalent to the non-static overloaded function
2812
2813        \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 27
2814
2815     \i Disconnect everything connected to a specific signal:
2816
2817        \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 28
2818
2819        equivalent to the non-static overloaded function
2820
2821        \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 29
2822
2823     \i Disconnect a specific receiver:
2824
2825        \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
2826
2827        equivalent to the non-static overloaded function
2828
2829        \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 31
2830
2831     \endlist
2832
2833     0 may be used as a wildcard, meaning "any signal", "any receiving
2834     object", or "any slot in the receiving object", respectively.
2835
2836     The \a sender may never be 0. (You cannot disconnect signals from
2837     more than one object in a single call.)
2838
2839     If \a signal is 0, it disconnects \a receiver and \a method from
2840     any signal. If not, only the specified signal is disconnected.
2841
2842     If \a receiver is 0, it disconnects anything connected to \a
2843     signal. If not, slots in objects other than \a receiver are not
2844     disconnected.
2845
2846     If \a method is 0, it disconnects anything that is connected to \a
2847     receiver. If not, only slots named \a method will be disconnected,
2848     and all other slots are left alone. The \a method must be 0 if \a
2849     receiver is left out, so you cannot disconnect a
2850     specifically-named slot on all objects.
2851
2852     \sa connect()
2853 */
2854 bool QObject::disconnect(const QObject *sender, const char *signal,
2855                          const QObject *receiver, const char *method)
2856 {
2857     if (sender == 0 || (receiver == 0 && method != 0)) {
2858         qWarning("Object::disconnect: Unexpected null parameter");
2859         return false;
2860     }
2861
2862     {
2863         const void *cbdata[] = { sender, signal, receiver, method };
2864         if (QInternal::activateCallbacks(QInternal::DisconnectCallback, (void **) cbdata))
2865             return true;
2866     }
2867
2868     const char *signal_arg = signal;
2869     QByteArray signal_name;
2870     bool signal_found = false;
2871     if (signal) {
2872         QT_TRY {
2873             signal_name = QMetaObject::normalizedSignature(signal);
2874             signal = signal_name.constData();
2875         } QT_CATCH (const std::bad_alloc &) {
2876             // if the signal is already normalized, we can continue.
2877             if (sender->metaObject()->indexOfSignal(signal + 1) == -1)
2878                 QT_RETHROW;
2879         }
2880
2881         if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
2882             return false;
2883         signal++; // skip code
2884     }
2885
2886     QByteArray method_name;
2887     const char *method_arg = method;
2888     int membcode = -1;
2889     bool method_found = false;
2890     if (method) {
2891         QT_TRY {
2892             method_name = QMetaObject::normalizedSignature(method);
2893             method = method_name.constData();
2894         } QT_CATCH(const std::bad_alloc &) {
2895             // if the method is already normalized, we can continue.
2896             if (receiver->metaObject()->indexOfMethod(method + 1) == -1)
2897                 QT_RETHROW;
2898         }
2899
2900         membcode = extract_code(method);
2901         if (!check_method_code(membcode, receiver, method, "disconnect"))
2902             return false;
2903         method++; // skip code
2904     }
2905
2906     /* We now iterate through all the sender's and receiver's meta
2907      * objects in order to also disconnect possibly shadowed signals
2908      * and slots with the same signature.
2909     */
2910     bool res = false;
2911     const QMetaObject *smeta = sender->metaObject();
2912     do {
2913         int signal_index = -1;
2914         if (signal) {
2915             signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
2916             if (signal_index < 0)
2917                 signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
2918             if (signal_index < 0)
2919                 break;
2920             signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2921             int signalOffset, methodOffset;
2922             computeOffsets(smeta, &signalOffset, &methodOffset);
2923             signal_index += signalOffset;
2924             signal_found = true;
2925         }
2926
2927         if (!method) {
2928             res |= QMetaObjectPrivate::disconnect(sender, signal_index, receiver, -1);
2929         } else {
2930             const QMetaObject *rmeta = receiver->metaObject();
2931             do {
2932                 int method_index = rmeta->indexOfMethod(method);
2933                 if (method_index >= 0)
2934                     while (method_index < rmeta->methodOffset())
2935                             rmeta = rmeta->superClass();
2936                 if (method_index < 0)
2937                     break;
2938                 res |= QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index);
2939                 method_found = true;
2940             } while ((rmeta = rmeta->superClass()));
2941         }
2942     } while (signal && (smeta = smeta->superClass()));
2943
2944     if (signal && !signal_found) {
2945         err_method_notfound(sender, signal_arg, "disconnect");
2946         err_info_about_objects("disconnect", sender, receiver);
2947     } else if (method && !method_found) {
2948         err_method_notfound(receiver, method_arg, "disconnect");
2949         err_info_about_objects("disconnect", sender, receiver);
2950     }
2951     if (res)
2952         const_cast<QObject*>(sender)->disconnectNotify(signal ? (signal - 1) : 0);
2953     return res;
2954 }
2955
2956 /*!
2957     \since 4.8
2958
2959     Disconnects \a signal in object \a sender from \a method in object
2960     \a receiver. Returns true if the connection is successfully broken;
2961     otherwise returns false.
2962
2963     This function provides the same possibilities like
2964     disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2965     but uses QMetaMethod to represent the signal and the method to be disconnected.
2966
2967     Additionally this function returnsfalse and no signals and slots disconnected
2968     if:
2969     \list 1
2970
2971         \i \a signal is not a member of sender class or one of its parent classes.
2972
2973         \i \a method is not a member of receiver class or one of its parent classes.
2974
2975         \i \a signal instance represents not a signal.
2976
2977     \endlist
2978
2979     QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
2980     In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
2981     method should also be QMetaMethod(). \a sender parameter should be never 0.
2982
2983     \sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2984  */
2985 bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
2986                          const QObject *receiver, const QMetaMethod &method)
2987 {
2988     if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
2989         qWarning("Object::disconnect: Unexpected null parameter");
2990         return false;
2991     }
2992     if (signal.mobj) {
2993         if(signal.methodType() != QMetaMethod::Signal) {
2994             qWarning("Object::%s: Attempt to %s non-signal %s::%s",
2995                      "disconnect","unbind",
2996                      sender->metaObject()->className(), signal.signature());
2997             return false;
2998         }
2999     }
3000     if (method.mobj) {
3001         if(method.methodType() == QMetaMethod::Constructor) {
3002             qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
3003                      receiver->metaObject()->className(), method.signature());
3004             return false;
3005         }
3006     }
3007
3008     QVarLengthArray<char> signalSignature;
3009     if (signal.mobj)
3010         QObjectPrivate::signalSignature(signal, &signalSignature);
3011
3012     {
3013         QByteArray methodSignature;
3014         if (method.mobj) {
3015             methodSignature.reserve(qstrlen(method.signature())+1);
3016             methodSignature.append((char)(method.methodType() == QMetaMethod::Slot ? QSLOT_CODE
3017                                         : method.methodType() == QMetaMethod::Signal ? QSIGNAL_CODE : 0  + '0'));
3018             methodSignature.append(method.signature());
3019         }
3020         const void *cbdata[] = { sender, signal.mobj ? signalSignature.constData() : 0,
3021                                  receiver, method.mobj ? methodSignature.constData() : 0 };
3022         if (QInternal::activateCallbacks(QInternal::DisconnectCallback, (void **) cbdata))
3023             return true;
3024     }
3025
3026     int signal_index;
3027     int method_index;
3028     {
3029         int dummy;
3030         QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
3031         QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
3032     }
3033     // If we are here sender is not null. If signal is not null while signal_index
3034     // is -1 then this signal is not a member of sender.
3035     if (signal.mobj && signal_index == -1) {
3036         qWarning("QObject::disconect: signal %s not found on class %s",
3037                  signal.signature(), sender->metaObject()->className());
3038         return false;
3039     }
3040     // If this condition is true then method is not a member of receeiver.
3041     if (receiver && method.mobj && method_index == -1) {
3042         qWarning("QObject::disconect: method %s not found on class %s",
3043                  method.signature(), receiver->metaObject()->className());
3044         return false;
3045     }
3046
3047     if (!QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index))
3048         return false;
3049
3050     const_cast<QObject*>(sender)->disconnectNotify(method.mobj ? signalSignature.constData() : 0);
3051     return true;
3052 }
3053
3054 /*!
3055     \threadsafe
3056
3057     \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method)
3058     \overload disconnect()
3059
3060     Disconnects \a signal from \a method of \a receiver.
3061
3062     A signal-slot connection is removed when either of the objects
3063     involved are destroyed.
3064 */
3065
3066 /*!
3067     \fn bool QObject::disconnect(const QObject *receiver, const char *method)
3068     \overload disconnect()
3069
3070     Disconnects all signals in this object from \a receiver's \a
3071     method.
3072
3073     A signal-slot connection is removed when either of the objects
3074     involved are destroyed.
3075 */
3076
3077
3078 /*!
3079     \fn void QObject::connectNotify(const char *signal)
3080
3081     This virtual function is called when something has been connected
3082     to \a signal in this object.
3083
3084     If you want to compare \a signal with a specific signal, use
3085     QLatin1String and the \c SIGNAL() macro as follows:
3086
3087     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 32
3088
3089     If the signal contains multiple parameters or parameters that
3090     contain spaces, call QMetaObject::normalizedSignature() on
3091     the result of the \c SIGNAL() macro.
3092
3093     \warning This function violates the object-oriented principle of
3094     modularity. However, it might be useful when you need to perform
3095     expensive initialization only if something is connected to a
3096     signal.
3097
3098     \sa connect(), disconnectNotify()
3099 */
3100
3101 void QObject::connectNotify(const char *)
3102 {
3103 }
3104
3105 /*!
3106     \fn void QObject::disconnectNotify(const char *signal)
3107
3108     This virtual function is called when something has been
3109     disconnected from \a signal in this object.
3110
3111     See connectNotify() for an example of how to compare
3112     \a signal with a specific signal.
3113
3114     \warning This function violates the object-oriented principle of
3115     modularity. However, it might be useful for optimizing access to
3116     expensive resources.
3117
3118     \sa disconnect(), connectNotify()
3119 */
3120
3121 void QObject::disconnectNotify(const char *)
3122 {
3123 }
3124
3125 /* \internal
3126     convert a signal index from the method range to the signal range
3127  */
3128 static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_index)
3129 {
3130     if (signal_index < 0)
3131         return signal_index;
3132     while (metaObject && metaObject->methodOffset() > signal_index)
3133         metaObject = metaObject->superClass();
3134
3135     if (metaObject) {
3136         int signalOffset, methodOffset;
3137         computeOffsets(metaObject, &signalOffset, &methodOffset);
3138         if (signal_index < metaObject->methodCount())
3139             signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
3140         else
3141             signal_index = signal_index - methodOffset + signalOffset;
3142     }
3143     return signal_index;
3144 }
3145
3146 /*!\internal
3147    \a types is a 0-terminated vector of meta types for queued
3148    connections.
3149
3150    if \a signal_index is -1, then we effectively connect *all* signals
3151    from the sender to the receiver's slot
3152  */
3153 bool QMetaObject::connect(const QObject *sender, int signal_index,
3154                           const QObject *receiver, int method_index, int type, int *types)
3155 {
3156     signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
3157     return QMetaObjectPrivate::connect(sender, signal_index,
3158                                        receiver, method_index,
3159                                        0, //FIXME, we could speed this connection up by computing the relative index
3160                                        type, types);
3161 }
3162
3163 /*! \internal
3164    Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3165
3166     method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
3167  */
3168 bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
3169                                  const QObject *receiver, int method_index,
3170                                  const QMetaObject *rmeta, int type, int *types)
3171 {
3172     QObject *s = const_cast<QObject *>(sender);
3173     QObject *r = const_cast<QObject *>(receiver);
3174
3175     int method_offset = rmeta ? rmeta->methodOffset() : 0;
3176     QObjectPrivate::StaticMetaCallFunction callFunction =
3177         (rmeta && QMetaObjectPrivate::get(rmeta)->revision >= 6 && rmeta->d.extradata)
3178         ? reinterpret_cast<const QMetaObjectExtraData *>(rmeta->d.extradata)->static_metacall : 0;
3179
3180     QOrderedMutexLocker locker(signalSlotLock(sender),
3181                                signalSlotLock(receiver));
3182
3183     if (type & Qt::UniqueConnection) {
3184         QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3185         if (connectionLists && connectionLists->count() > signal_index) {
3186             const QObjectPrivate::Connection *c2 =
3187                 (*connectionLists)[signal_index].first;
3188
3189             int method_index_absolute = method_index + method_offset;
3190
3191             while (c2) {
3192                 if (c2->receiver == receiver && c2->method() == method_index_absolute)
3193                     return false;
3194                 c2 = c2->nextConnectionList;
3195             }
3196         }
3197         type &= Qt::UniqueConnection - 1;
3198     }
3199
3200     QObjectPrivate::Connection *c = new QObjectPrivate::Connection;
3201     c->sender = s;
3202     c->receiver = r;
3203     c->method_relative = method_index;
3204     c->method_offset = method_offset;
3205     c->connectionType = type;
3206     c->argumentTypes = types;
3207     c->nextConnectionList = 0;
3208     c->callFunction = callFunction;
3209
3210     QT_TRY {
3211         QObjectPrivate::get(s)->addConnection(signal_index, c);
3212     } QT_CATCH(...) {
3213         delete c;
3214         QT_RETHROW;
3215     }
3216
3217     c->prev = &(QObjectPrivate::get(r)->senders);
3218     c->next = *c->prev;
3219     *c->prev = c;
3220     if (c->next)
3221         c->next->prev = &c->next;
3222
3223     QObjectPrivate *const sender_d = QObjectPrivate::get(s);
3224     if (signal_index < 0) {
3225         sender_d->connectedSignals[0] = sender_d->connectedSignals[1] = ~0;
3226     } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) {
3227         sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f));
3228     }
3229
3230     return true;
3231 }
3232
3233 /*!\internal
3234  */
3235 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
3236                              const QObject *receiver, int method_index)
3237 {
3238     signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
3239     return QMetaObjectPrivate::disconnect(sender, signal_index,
3240                                           receiver, method_index);
3241 }
3242
3243 /*!\internal
3244
3245 Disconnect a single signal connection.  If QMetaObject::connect() has been called 
3246 multiple times for the same sender, signal_index, receiver and method_index only 
3247 one of these connections will be removed.
3248  */
3249 bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
3250                                 const QObject *receiver, int method_index)
3251 {
3252     signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
3253     return QMetaObjectPrivate::disconnect(sender, signal_index,
3254                                           receiver, method_index,
3255                                           QMetaObjectPrivate::DisconnectOne);
3256 }
3257
3258 /*! \internal
3259     Helper function to remove the connection from the senders list and setting the receivers to 0
3260  */
3261 bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
3262                                           const QObject *receiver, int method_index,
3263                                           QMutex *senderMutex, DisconnectType disconnectType)
3264 {
3265     bool success = false;
3266     while (c) {
3267         if (c->receiver
3268             && (receiver == 0 || (c->receiver == receiver
3269                            && (method_index < 0 || c->method() == method_index)))) {
3270             bool needToUnlock = false;
3271             QMutex *receiverMutex = 0;
3272             if (!receiver) {
3273                 receiverMutex = signalSlotLock(c->receiver);
3274                 // need to relock this receiver and sender in the correct order
3275                 needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
3276             }
3277             if (c->receiver) {
3278                 *c->prev = c->next;
3279                 if (c->next)
3280                     c->next->prev = c->prev;
3281             }
3282
3283             if (needToUnlock)
3284                 receiverMutex->unlockInline();
3285
3286             c->receiver = 0;
3287
3288             success = true;
3289
3290             if (disconnectType == DisconnectOne)
3291                 return success;
3292         }
3293         c = c->nextConnectionList;
3294     }
3295     return success;
3296 }
3297
3298 /*! \internal
3299     Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3300  */
3301 bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
3302                                     const QObject *receiver, int method_index,
3303                                     DisconnectType disconnectType)
3304 {
3305     if (!sender)
3306         return false;
3307
3308     QObject *s = const_cast<QObject *>(sender);
3309
3310     QMutex *senderMutex = signalSlotLock(sender);
3311     QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
3312     QOrderedMutexLocker locker(senderMutex, receiverMutex);
3313
3314     QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3315     if (!connectionLists)
3316         return false;
3317
3318     // prevent incoming connections changing the connectionLists while unlocked
3319     ++connectionLists->inUse;
3320
3321     bool success = false;
3322     if (signal_index < 0) {
3323         // remove from all connection lists
3324         for (signal_index = -1; signal_index < connectionLists->count(); ++signal_index) {
3325             QObjectPrivate::Connection *c =
3326                 (*connectionLists)[signal_index].first;
3327             if (disconnectHelper(c, receiver, method_index, senderMutex, disconnectType)) {
3328                 success = true;
3329                 connectionLists->dirty = true;
3330             }
3331         }
3332     } else if (signal_index < connectionLists->count()) {
3333         QObjectPrivate::Connection *c =
3334             (*connectionLists)[signal_index].first;
3335         if (disconnectHelper(c, receiver, method_index, senderMutex, disconnectType)) {
3336             success = true;
3337             connectionLists->dirty = true;
3338         }
3339     }
3340
3341     --connectionLists->inUse;
3342     Q_ASSERT(connectionLists->inUse >= 0);
3343     if (connectionLists->orphaned && !connectionLists->inUse)
3344         delete connectionLists;
3345
3346     return success;
3347 }
3348
3349 /*!
3350     \fn void QMetaObject::connectSlotsByName(QObject *object)
3351
3352     Searches recursively for all child objects of the given \a object, and connects
3353     matching signals from them to slots of \a object that follow the following form:
3354
3355     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 33
3356
3357     Let's assume our object has a child object of type QPushButton with
3358     the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
3359     button's \c{clicked()} signal would be:
3360
3361     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 34
3362
3363     \sa QObject::setObjectName()
3364  */
3365 void QMetaObject::connectSlotsByName(QObject *o)
3366 {
3367     if (!o)
3368         return;
3369     const QMetaObject *mo = o->metaObject();
3370     Q_ASSERT(mo);
3371     const QObjectList list = o->findChildren<QObject *>(QString());
3372     for (int i = 0; i < mo->methodCount(); ++i) {
3373         const char *slot = mo->method(i).signature();
3374         Q_ASSERT(slot);
3375         if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
3376             continue;
3377         bool foundIt = false;
3378         for(int j = 0; j < list.count(); ++j) {
3379             const QObject *co = list.at(j);
3380             QByteArray objName = co->objectName().toAscii();
3381             int len = objName.length();
3382             if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
3383                 continue;
3384             int sigIndex = co->d_func()->signalIndex(slot + len + 4);
3385             if (sigIndex < 0) { // search for compatible signals
3386                 const QMetaObject *smo = co->metaObject();
3387                 int slotlen = qstrlen(slot + len + 4) - 1;
3388                 for (int k = 0; k < co->metaObject()->methodCount(); ++k) {
3389                     QMetaMethod method = smo->method(k);
3390                     if (method.methodType() != QMetaMethod::Signal)
3391                         continue;
3392
3393                     if (!qstrncmp(method.signature(), slot + len + 4, slotlen)) {
3394                         int signalOffset, methodOffset;
3395                         computeOffsets(method.enclosingMetaObject(), &signalOffset, &methodOffset);
3396                         sigIndex = k + - methodOffset + signalOffset;
3397                         break;
3398                     }
3399                 }
3400             }
3401             if (sigIndex < 0)
3402                 continue;
3403             if (QMetaObjectPrivate::connect(co, sigIndex, o, i)) {
3404                 foundIt = true;
3405                 break;
3406             }
3407         }
3408         if (foundIt) {
3409             // we found our slot, now skip all overloads
3410             while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
3411                   ++i;
3412         } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
3413             qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
3414         }
3415     }
3416 }
3417
3418 static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
3419 {
3420     if (!c->argumentTypes && c->argumentTypes != &DIRECT_CONNECTION_ONLY) {
3421         QMetaMethod m = sender->metaObject()->method(signal);
3422         int *tmp = queuedConnectionTypes(m.parameterTypes());
3423         if (!tmp) // cannot queue arguments
3424             tmp = &DIRECT_CONNECTION_ONLY;
3425         if (!c->argumentTypes.testAndSetOrdered(0, tmp)) {
3426             if (tmp != &DIRECT_CONNECTION_ONLY)
3427                 delete [] tmp;
3428         }
3429     }
3430     if (c->argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
3431         return;
3432     int nargs = 1; // include return type
3433     while (c->argumentTypes[nargs-1])
3434         ++nargs;
3435     int *types = (int *) qMalloc(nargs*sizeof(int));
3436     Q_CHECK_PTR(types);
3437     void **args = (void **) qMalloc(nargs*sizeof(void *));
3438     Q_CHECK_PTR(args);
3439     types[0] = 0; // return type
3440     args[0] = 0; // return value
3441     for (int n = 1; n < nargs; ++n)
3442         args[n] = QMetaType::construct((types[n] = c->argumentTypes[n-1]), argv[n]);
3443     QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method_offset,
3444                                                                 c->method_relative,
3445                                                                 c->callFunction,
3446                                                                 sender, signal, nargs,
3447                                                                 types, args));
3448 }
3449
3450
3451 /*!\internal
3452    \obsolete.
3453    Used to be called from QMetaObject::activate(QObject *, QMetaObject *, int, int, void **) before Qt 4.6
3454  */
3455 void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal_index, void **argv)
3456 {
3457     Q_UNUSED(to_signal_index);
3458     activate(sender, from_signal_index, argv);
3459 }
3460
3461 /*!\internal
3462  */
3463 void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
3464                            void **argv)
3465 {
3466     int signalOffset;
3467     int methodOffset;
3468     computeOffsets(m, &signalOffset, &methodOffset);
3469
3470     int signal_index = signalOffset + local_signal_index;
3471
3472     if (!sender->d_func()->isSignalConnected(signal_index))
3473         return; // nothing connected to these signals, and no spy
3474
3475     if (sender->d_func()->blockSig)
3476         return;
3477
3478     int signal_absolute_index = methodOffset + local_signal_index;
3479
3480     void *empty_argv[] = { 0 };
3481     if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
3482         qt_signal_spy_callback_set.signal_begin_callback(sender, signal_absolute_index,
3483                                                          argv ? argv : empty_argv);
3484     }
3485
3486     Qt::HANDLE currentThreadId = QThread::currentThreadId();
3487
3488     QMutexLocker locker(signalSlotLock(sender));
3489     QObjectConnectionListVector *connectionLists = sender->d_func()->connectionLists;
3490     if (!connectionLists) {
3491         locker.unlock();
3492         if (qt_signal_spy_callback_set.signal_end_callback != 0)
3493             qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3494         return;
3495     }
3496     ++connectionLists->inUse;
3497
3498
3499     const QObjectPrivate::ConnectionList *list;
3500     if (signal_index < connectionLists->count())
3501         list = &connectionLists->at(signal_index);
3502     else
3503         list = &connectionLists->allsignals;
3504
3505     do {
3506         QObjectPrivate::Connection *c = list->first;
3507         if (!c) continue;
3508         // We need to check against last here to ensure that signals added
3509         // during the signal emission are not emitted in this emission.
3510         QObjectPrivate::Connection *last = list->last;
3511
3512         do {
3513             if (!c->receiver)
3514                 continue;
3515
3516             QObject * const receiver = c->receiver;
3517             const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
3518
3519             // determine if this connection should be sent immediately or
3520             // put into the event queue
3521             if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
3522                 || (c->connectionType == Qt::QueuedConnection)) {
3523                 queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
3524                 continue;
3525 #ifndef QT_NO_THREAD
3526             } else if (c->connectionType == Qt::BlockingQueuedConnection) {
3527                 locker.unlock();
3528                 if (receiverInSameThread) {
3529                     qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "