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