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