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