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