Pashto uses Arabic script and is written right to left
[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     int signalOffset;
2236     int methodOffset;
2237     computeOffsets(signal.mobj, &signalOffset, &methodOffset);
2238     signalIndex += signalOffset;
2239
2240     if (signalIndex < sizeof(d->connectedSignals) * 8)
2241         return d->isSignalConnected(signalIndex);
2242
2243     QMutexLocker locker(signalSlotLock(this));
2244     if (d->connectionLists) {
2245         if (signalIndex < uint(d->connectionLists->count())) {
2246             const QObjectPrivate::Connection *c =
2247                 d->connectionLists->at(signalIndex).first;
2248             while (c) {
2249                 if (c->receiver)
2250                     return true;
2251                 c = c->nextConnectionList;
2252             }
2253         }
2254     }
2255     return false;
2256 }
2257
2258 /*!
2259     \internal
2260
2261     This helper function calculates signal and method index for the given
2262     member in the specified class.
2263
2264     \list
2265     \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
2266
2267     \li If specified member is not a member of obj instance class (or one of
2268     its parent classes) then both signalIndex and methodIndex are set to -1.
2269     \endlist
2270
2271     This function is used by QObject::connect and QObject::disconnect which
2272     are working with QMetaMethod.
2273
2274     \a signalIndex is set to the signal index of member. If the member
2275     specified is not signal this variable is set to -1.
2276
2277     \a methodIndex is set to the method index of the member. If the
2278     member is not a method of the object specified by the \a obj argument this
2279     variable is set to -1.
2280 */
2281 void QMetaObjectPrivate::memberIndexes(const QObject *obj,
2282                                        const QMetaMethod &member,
2283                                        int *signalIndex, int *methodIndex)
2284 {
2285     *signalIndex = -1;
2286     *methodIndex = -1;
2287     if (!obj || !member.mobj)
2288         return;
2289     const QMetaObject *m = obj->metaObject();
2290     // Check that member is member of obj class
2291     while (m != 0 && m != member.mobj)
2292         m = m->d.superdata;
2293     if (!m)
2294         return;
2295     *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
2296
2297     int signalOffset;
2298     int methodOffset;
2299     computeOffsets(m, &signalOffset, &methodOffset);
2300
2301     *methodIndex += methodOffset;
2302     if (member.methodType() == QMetaMethod::Signal) {
2303         *signalIndex = originalClone(m, *signalIndex);
2304         *signalIndex += signalOffset;
2305     } else {
2306         *signalIndex = -1;
2307     }
2308 }
2309
2310 static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
2311                                          const QMetaObject *receiver, const QMetaMethod &method)
2312 {
2313     if (signal.attributes() & QMetaMethod::Compatibility) {
2314         if (!(method.attributes() & QMetaMethod::Compatibility))
2315             qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
2316                      sender->className(), signal.methodSignature().constData());
2317     } else if ((method.attributes() & QMetaMethod::Compatibility) &&
2318                method.methodType() == QMetaMethod::Signal) {
2319         qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
2320                  sender->className(), signal.methodSignature().constData(),
2321                  receiver->className(), method.methodSignature().constData());
2322     }
2323 }
2324
2325 /*!
2326     \threadsafe
2327
2328     Creates a connection of the given \a type from the \a signal in
2329     the \a sender object to the \a method in the \a receiver object.
2330     Returns a handle to the connection that can be used to disconnect
2331     it later.
2332
2333     You must use the \c SIGNAL() and \c SLOT() macros when specifying
2334     the \a signal and the \a method, for example:
2335
2336     \snippet code/src_corelib_kernel_qobject.cpp 22
2337
2338     This example ensures that the label always displays the current
2339     scroll bar value. Note that the signal and slots parameters must not
2340     contain any variable names, only the type. E.g. the following would
2341     not work and return false:
2342
2343     \snippet code/src_corelib_kernel_qobject.cpp 23
2344
2345     A signal can also be connected to another signal:
2346
2347     \snippet code/src_corelib_kernel_qobject.cpp 24
2348
2349     In this example, the \c MyWidget constructor relays a signal from
2350     a private member variable, and makes it available under a name
2351     that relates to \c MyWidget.
2352
2353     A signal can be connected to many slots and signals. Many signals
2354     can be connected to one slot.
2355
2356     If a signal is connected to several slots, the slots are activated
2357     in the same order as the order the connection was made, when the
2358     signal is emitted.
2359
2360     The function returns a handle to a connection if it successfully
2361     connects the signal to the slot. The Connection handle will be invalid
2362     if it cannot create the connection, for example, if QObject is unable
2363     to verify the existence of either \a signal or \a method, or if their
2364     signatures aren't compatible.
2365     You can check if the QMetaObject::Connection is valid by casting it to a bool.
2366
2367     By default, a signal is emitted for every connection you make;
2368     two signals are emitted for duplicate connections. You can break
2369     all of these connections with a single disconnect() call.
2370     If you pass the Qt::UniqueConnection \a type, the connection will only
2371     be made if it is not a duplicate. If there is already a duplicate
2372     (exact same signal to the exact same slot on the same objects),
2373     the connection will fail and connect will return an invalid QMetaObject::Connection.
2374
2375     The optional \a type parameter describes the type of connection
2376     to establish. In particular, it determines whether a particular
2377     signal is delivered to a slot immediately or queued for delivery
2378     at a later time. If the signal is queued, the parameters must be
2379     of types that are known to Qt's meta-object system, because Qt
2380     needs to copy the arguments to store them in an event behind the
2381     scenes. If you try to use a queued connection and get the error
2382     message
2383
2384     \snippet code/src_corelib_kernel_qobject.cpp 25
2385
2386     call qRegisterMetaType() to register the data type before you
2387     establish the connection.
2388
2389     \sa disconnect(), sender(), qRegisterMetaType(), Q_DECLARE_METATYPE()
2390 */
2391 QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,
2392                                      const QObject *receiver, const char *method,
2393                                      Qt::ConnectionType type)
2394 {
2395     if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
2396         qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2397                  sender ? sender->metaObject()->className() : "(null)",
2398                  (signal && *signal) ? signal+1 : "(null)",
2399                  receiver ? receiver->metaObject()->className() : "(null)",
2400                  (method && *method) ? method+1 : "(null)");
2401         return QMetaObject::Connection(0);
2402     }
2403     QByteArray tmp_signal_name;
2404
2405     if (!check_signal_macro(sender, signal, "connect", "bind"))
2406         return QMetaObject::Connection(0);
2407     const QMetaObject *smeta = sender->metaObject();
2408     const char *signal_arg = signal;
2409     ++signal; //skip code
2410     QArgumentTypeArray signalTypes;
2411     Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2412     QByteArray signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2413     int signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2414             &smeta, signalName, signalTypes.size(), signalTypes.constData());
2415     if (signal_index < 0) {
2416         // check for normalized signatures
2417         tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
2418         signal = tmp_signal_name.constData() + 1;
2419
2420         signalTypes.clear();
2421         signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2422         smeta = sender->metaObject();
2423         signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2424                 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2425     }
2426     if (signal_index < 0) {
2427         err_method_notfound(sender, signal_arg, "connect");
2428         err_info_about_objects("connect", sender, receiver);
2429         return QMetaObject::Connection(0);
2430     }
2431     signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2432     int signalOffset, methodOffset;
2433     computeOffsets(smeta, &signalOffset, &methodOffset);
2434     signal_index += signalOffset;
2435
2436     QByteArray tmp_method_name;
2437     int membcode = extract_code(method);
2438
2439     if (!check_method_code(membcode, receiver, method, "connect"))
2440         return QMetaObject::Connection(0);
2441     const char *method_arg = method;
2442     ++method; // skip code
2443
2444     QByteArray methodName;
2445     QArgumentTypeArray methodTypes;
2446     const QMetaObject *rmeta = receiver->metaObject();
2447     int method_index_relative = -1;
2448     Q_ASSERT(QMetaObjectPrivate::get(rmeta)->revision >= 7);
2449     switch (membcode) {
2450     case QSLOT_CODE:
2451         method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2452                 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2453         break;
2454     case QSIGNAL_CODE:
2455         method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2456                 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2457         break;
2458     }
2459     if (method_index_relative < 0) {
2460         // check for normalized methods
2461         tmp_method_name = QMetaObject::normalizedSignature(method);
2462         method = tmp_method_name.constData();
2463
2464         methodTypes.clear();
2465         methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2466         // rmeta may have been modified above
2467         rmeta = receiver->metaObject();
2468         switch (membcode) {
2469         case QSLOT_CODE:
2470             method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2471                     &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2472             break;
2473         case QSIGNAL_CODE:
2474             method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2475                     &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2476             break;
2477         }
2478     }
2479
2480     if (method_index_relative < 0) {
2481         err_method_notfound(receiver, method_arg, "connect");
2482         err_info_about_objects("connect", sender, receiver);
2483         return QMetaObject::Connection(0);
2484     }
2485
2486     if (!QMetaObjectPrivate::checkConnectArgs(signalTypes.size(), signalTypes.constData(),
2487                                               methodTypes.size(), methodTypes.constData())) {
2488         qWarning("QObject::connect: Incompatible sender/receiver arguments"
2489                  "\n        %s::%s --> %s::%s",
2490                  sender->metaObject()->className(), signal,
2491                  receiver->metaObject()->className(), method);
2492         return QMetaObject::Connection(0);
2493     }
2494
2495     int *types = 0;
2496     if ((type == Qt::QueuedConnection)
2497             && !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {
2498         return QMetaObject::Connection(0);
2499     }
2500
2501 #ifndef QT_NO_DEBUG
2502     QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
2503     QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
2504     check_and_warn_compat(smeta, smethod, rmeta, rmethod);
2505 #endif
2506     QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2507         sender, signal_index, smeta, receiver, method_index_relative, rmeta ,type, types));
2508     return handle;
2509 }
2510
2511 /*!
2512     \since 4.8
2513
2514     Creates a connection of the given \a type from the \a signal in
2515     the \a sender object to the \a method in the \a receiver object.
2516     Returns a handle to the connection that can be used to disconnect
2517     it later.
2518
2519     The Connection handle will be invalid  if it cannot create the
2520     connection, for example, the parameters were invalid.
2521     You can check if the QMetaObject::Connection is valid by casting it to a bool.
2522
2523     This function works in the same way as
2524     connect(const QObject *sender, const char *signal,
2525             const QObject *receiver, const char *method,
2526             Qt::ConnectionType type)
2527     but it uses QMetaMethod to specify signal and method.
2528
2529     \sa connect(const QObject *sender, const char *signal,
2530                 const QObject *receiver, const char *method,
2531                 Qt::ConnectionType type)
2532  */
2533 QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal,
2534                                      const QObject *receiver, const QMetaMethod &method,
2535                                      Qt::ConnectionType type)
2536 {
2537     if (sender == 0
2538             || receiver == 0
2539             || signal.methodType() != QMetaMethod::Signal
2540             || method.methodType() == QMetaMethod::Constructor) {
2541         qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2542                  sender ? sender->metaObject()->className() : "(null)",
2543                  signal.methodSignature().constData(),
2544                  receiver ? receiver->metaObject()->className() : "(null)",
2545                  method.methodSignature().constData() );
2546         return QMetaObject::Connection(0);
2547     }
2548
2549     int signal_index;
2550     int method_index;
2551     {
2552         int dummy;
2553         QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2554         QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2555     }
2556
2557     const QMetaObject *smeta = sender->metaObject();
2558     const QMetaObject *rmeta = receiver->metaObject();
2559     if (signal_index == -1) {
2560         qWarning("QObject::connect: Can't find signal %s on instance of class %s",
2561                  signal.methodSignature().constData(), smeta->className());
2562         return QMetaObject::Connection(0);
2563     }
2564     if (method_index == -1) {
2565         qWarning("QObject::connect: Can't find method %s on instance of class %s",
2566                  method.methodSignature().constData(), rmeta->className());
2567         return QMetaObject::Connection(0);
2568     }
2569
2570     if (!QMetaObject::checkConnectArgs(signal.methodSignature().constData(), method.methodSignature().constData())) {
2571         qWarning("QObject::connect: Incompatible sender/receiver arguments"
2572                  "\n        %s::%s --> %s::%s",
2573                  smeta->className(), signal.methodSignature().constData(),
2574                  rmeta->className(), method.methodSignature().constData());
2575         return QMetaObject::Connection(0);
2576     }
2577
2578     int *types = 0;
2579     if ((type == Qt::QueuedConnection)
2580             && !(types = queuedConnectionTypes(signal.parameterTypes())))
2581         return QMetaObject::Connection(0);
2582
2583 #ifndef QT_NO_DEBUG
2584     check_and_warn_compat(smeta, signal, rmeta, method);
2585 #endif
2586     QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2587         sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, 0, type, types));
2588     return handle;
2589 }
2590
2591 /*!
2592     \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
2593     \overload connect()
2594     \threadsafe
2595
2596     Connects \a signal from the \a sender object to this object's \a
2597     method.
2598
2599     Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
2600
2601     Every connection you make emits a signal, so duplicate connections emit
2602     two signals. You can break a connection using disconnect().
2603
2604     \sa disconnect()
2605 */
2606
2607 /*!
2608     \threadsafe
2609
2610     Disconnects \a signal in object \a sender from \a method in object
2611     \a receiver. Returns true if the connection is successfully broken;
2612     otherwise returns false.
2613
2614     A signal-slot connection is removed when either of the objects
2615     involved are destroyed.
2616
2617     disconnect() is typically used in three ways, as the following
2618     examples demonstrate.
2619     \list 1
2620     \li Disconnect everything connected to an object's signals:
2621
2622        \snippet code/src_corelib_kernel_qobject.cpp 26
2623
2624        equivalent to the non-static overloaded function
2625
2626        \snippet code/src_corelib_kernel_qobject.cpp 27
2627
2628     \li Disconnect everything connected to a specific signal:
2629
2630        \snippet code/src_corelib_kernel_qobject.cpp 28
2631
2632        equivalent to the non-static overloaded function
2633
2634        \snippet code/src_corelib_kernel_qobject.cpp 29
2635
2636     \li Disconnect a specific receiver:
2637
2638        \snippet code/src_corelib_kernel_qobject.cpp 30
2639
2640        equivalent to the non-static overloaded function
2641
2642        \snippet code/src_corelib_kernel_qobject.cpp 31
2643
2644     \endlist
2645
2646     0 may be used as a wildcard, meaning "any signal", "any receiving
2647     object", or "any slot in the receiving object", respectively.
2648
2649     The \a sender may never be 0. (You cannot disconnect signals from
2650     more than one object in a single call.)
2651
2652     If \a signal is 0, it disconnects \a receiver and \a method from
2653     any signal. If not, only the specified signal is disconnected.
2654
2655     If \a receiver is 0, it disconnects anything connected to \a
2656     signal. If not, slots in objects other than \a receiver are not
2657     disconnected.
2658
2659     If \a method is 0, it disconnects anything that is connected to \a
2660     receiver. If not, only slots named \a method will be disconnected,
2661     and all other slots are left alone. The \a method must be 0 if \a
2662     receiver is left out, so you cannot disconnect a
2663     specifically-named slot on all objects.
2664
2665     \sa connect()
2666 */
2667 bool QObject::disconnect(const QObject *sender, const char *signal,
2668                          const QObject *receiver, const char *method)
2669 {
2670     if (sender == 0 || (receiver == 0 && method != 0)) {
2671         qWarning("QObject::disconnect: Unexpected null parameter");
2672         return false;
2673     }
2674
2675     const char *signal_arg = signal;
2676     QByteArray signal_name;
2677     bool signal_found = false;
2678     if (signal) {
2679         QT_TRY {
2680             signal_name = QMetaObject::normalizedSignature(signal);
2681             signal = signal_name.constData();
2682         } QT_CATCH (const std::bad_alloc &) {
2683             // if the signal is already normalized, we can continue.
2684             if (sender->metaObject()->indexOfSignal(signal + 1) == -1)
2685                 QT_RETHROW;
2686         }
2687
2688         if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
2689             return false;
2690         signal++; // skip code
2691     }
2692
2693     QByteArray method_name;
2694     const char *method_arg = method;
2695     int membcode = -1;
2696     bool method_found = false;
2697     if (method) {
2698         QT_TRY {
2699             method_name = QMetaObject::normalizedSignature(method);
2700             method = method_name.constData();
2701         } QT_CATCH(const std::bad_alloc &) {
2702             // if the method is already normalized, we can continue.
2703             if (receiver->metaObject()->indexOfMethod(method + 1) == -1)
2704                 QT_RETHROW;
2705         }
2706
2707         membcode = extract_code(method);
2708         if (!check_method_code(membcode, receiver, method, "disconnect"))
2709             return false;
2710         method++; // skip code
2711     }
2712
2713     /* We now iterate through all the sender's and receiver's meta
2714      * objects in order to also disconnect possibly shadowed signals
2715      * and slots with the same signature.
2716     */
2717     bool res = false;
2718     const QMetaObject *smeta = sender->metaObject();
2719     QByteArray signalName;
2720     QArgumentTypeArray signalTypes;
2721     Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2722     if (signal)
2723         signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2724     QByteArray methodName;
2725     QArgumentTypeArray methodTypes;
2726     Q_ASSERT(!receiver || QMetaObjectPrivate::get(receiver->metaObject())->revision >= 7);
2727     if (method)
2728         methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2729     do {
2730         int signal_index = -1;
2731         if (signal) {
2732             signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2733                         &smeta, signalName, signalTypes.size(), signalTypes.constData());
2734             if (signal_index < 0)
2735                 break;
2736             signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2737             int signalOffset, methodOffset;
2738             computeOffsets(smeta, &signalOffset, &methodOffset);
2739             signal_index += signalOffset;
2740             signal_found = true;
2741         }
2742
2743         if (!method) {
2744             res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, 0);
2745         } else {
2746             const QMetaObject *rmeta = receiver->metaObject();
2747             do {
2748                 int method_index = QMetaObjectPrivate::indexOfMethod(
2749                             rmeta, methodName, methodTypes.size(), methodTypes.constData());
2750                 if (method_index >= 0)
2751                     while (method_index < rmeta->methodOffset())
2752                             rmeta = rmeta->superClass();
2753                 if (method_index < 0)
2754                     break;
2755                 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, 0);
2756                 method_found = true;
2757             } while ((rmeta = rmeta->superClass()));
2758         }
2759     } while (signal && (smeta = smeta->superClass()));
2760
2761     if (signal && !signal_found) {
2762         err_method_notfound(sender, signal_arg, "disconnect");
2763         err_info_about_objects("disconnect", sender, receiver);
2764     } else if (method && !method_found) {
2765         err_method_notfound(receiver, method_arg, "disconnect");
2766         err_info_about_objects("disconnect", sender, receiver);
2767     }
2768     if (res) {
2769         if (!signal)
2770             const_cast<QObject*>(sender)->disconnectNotify(QMetaMethod());
2771     }
2772     return res;
2773 }
2774
2775 /*!
2776     \since 4.8
2777
2778     Disconnects \a signal in object \a sender from \a method in object
2779     \a receiver. Returns true if the connection is successfully broken;
2780     otherwise returns false.
2781
2782     This function provides the same possibilities like
2783     disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2784     but uses QMetaMethod to represent the signal and the method to be disconnected.
2785
2786     Additionally this function returnsfalse and no signals and slots disconnected
2787     if:
2788     \list 1
2789
2790         \li \a signal is not a member of sender class or one of its parent classes.
2791
2792         \li \a method is not a member of receiver class or one of its parent classes.
2793
2794         \li \a signal instance represents not a signal.
2795
2796     \endlist
2797
2798     QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
2799     In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
2800     method should also be QMetaMethod(). \a sender parameter should be never 0.
2801
2802     \sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2803  */
2804 bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
2805                          const QObject *receiver, const QMetaMethod &method)
2806 {
2807     if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
2808         qWarning("QObject::disconnect: Unexpected null parameter");
2809         return false;
2810     }
2811     if (signal.mobj) {
2812         if(signal.methodType() != QMetaMethod::Signal) {
2813             qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
2814                      "disconnect","unbind",
2815                      sender->metaObject()->className(), signal.methodSignature().constData());
2816             return false;
2817         }
2818     }
2819     if (method.mobj) {
2820         if(method.methodType() == QMetaMethod::Constructor) {
2821             qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
2822                      receiver->metaObject()->className(), method.methodSignature().constData());
2823             return false;
2824         }
2825     }
2826
2827     // Reconstructing SIGNAL() macro result for signal.methodSignature() string
2828     QByteArray signalSignature;
2829     if (signal.mobj) {
2830         signalSignature.reserve(signal.methodSignature().size()+1);
2831         signalSignature.append((char)(QSIGNAL_CODE + '0'));
2832         signalSignature.append(signal.methodSignature());
2833     }
2834
2835     int signal_index;
2836     int method_index;
2837     {
2838         int dummy;
2839         QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2840         QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2841     }
2842     // If we are here sender is not null. If signal is not null while signal_index
2843     // is -1 then this signal is not a member of sender.
2844     if (signal.mobj && signal_index == -1) {
2845         qWarning("QObject::disconect: signal %s not found on class %s",
2846                  signal.methodSignature().constData(), sender->metaObject()->className());
2847         return false;
2848     }
2849     // If this condition is true then method is not a member of receeiver.
2850     if (receiver && method.mobj && method_index == -1) {
2851         qWarning("QObject::disconect: method %s not found on class %s",
2852                  method.methodSignature().constData(), receiver->metaObject()->className());
2853         return false;
2854     }
2855
2856     if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, 0))
2857         return false;
2858
2859     if (!signal.isValid()) {
2860         // The signal is a wildcard, meaning all signals were disconnected.
2861         // QMetaObjectPrivate::disconnect() doesn't call disconnectNotify()
2862         // per connection in this case. Call it once now, with an invalid
2863         // QMetaMethod as argument, as documented.
2864         const_cast<QObject*>(sender)->disconnectNotify(signal);
2865     }
2866     return true;
2867 }
2868
2869 /*!
2870     \threadsafe
2871
2872     \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method) const
2873     \overload disconnect()
2874
2875     Disconnects \a signal from \a method of \a receiver.
2876
2877     A signal-slot connection is removed when either of the objects
2878     involved are destroyed.
2879 */
2880
2881 /*!
2882     \fn bool QObject::disconnect(const QObject *receiver, const char *method) const
2883     \overload disconnect()
2884
2885     Disconnects all signals in this object from \a receiver's \a
2886     method.
2887
2888     A signal-slot connection is removed when either of the objects
2889     involved are destroyed.
2890 */
2891
2892
2893 /*!
2894     \since 5.0
2895
2896     This virtual function is called when something has been connected
2897     to \a signal in this object.
2898
2899     If you want to compare \a signal with a specific signal, you can
2900     use QMetaMethod::fromSignal() as follows:
2901
2902     \snippet code/src_corelib_kernel_qobject.cpp 32
2903
2904     \warning This function violates the object-oriented principle of
2905     modularity. However, it might be useful when you need to perform
2906     expensive initialization only if something is connected to a
2907     signal.
2908
2909     \sa connect(), disconnectNotify()
2910 */
2911
2912 void QObject::connectNotify(const QMetaMethod &signal)
2913 {
2914     Q_UNUSED(signal);
2915 }
2916
2917 /*!
2918     \since 5.0
2919
2920     This virtual function is called when something has been
2921     disconnected from \a signal in this object.
2922
2923     See connectNotify() for an example of how to compare
2924     \a signal with a specific signal.
2925
2926     If all signals were disconnected from this object (e.g., the
2927     signal argument to disconnect() was 0), disconnectNotify()
2928     is only called once, and the \a signal will be an invalid
2929     QMetaMethod (QMetaMethod::isValid() returns false).
2930
2931     \warning This function violates the object-oriented principle of
2932     modularity. However, it might be useful for optimizing access to
2933     expensive resources.
2934
2935     \sa disconnect(), connectNotify()
2936 */
2937
2938 void QObject::disconnectNotify(const QMetaMethod &signal)
2939 {
2940     Q_UNUSED(signal);
2941 }
2942
2943 /* \internal
2944     convert a signal index from the method range to the signal range
2945  */
2946 static int methodIndexToSignalIndex(const QMetaObject **base, int signal_index)
2947 {
2948     if (signal_index < 0)
2949         return signal_index;
2950     const QMetaObject *metaObject = *base;
2951     while (metaObject && metaObject->methodOffset() > signal_index)
2952         metaObject = metaObject->superClass();
2953
2954     if (metaObject) {
2955         int signalOffset, methodOffset;
2956         computeOffsets(metaObject, &signalOffset, &methodOffset);
2957         if (signal_index < metaObject->methodCount())
2958             signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
2959         else
2960             signal_index = signal_index - methodOffset + signalOffset;
2961         *base = metaObject;
2962     }
2963     return signal_index;
2964 }
2965
2966 /*!\internal
2967    \a types is a 0-terminated vector of meta types for queued
2968    connections.
2969
2970    if \a signal_index is -1, then we effectively connect *all* signals
2971    from the sender to the receiver's slot
2972  */
2973 QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_index,
2974                                           const QObject *receiver, int method_index, int type, int *types)
2975 {
2976     const QMetaObject *smeta = sender->metaObject();
2977     signal_index = methodIndexToSignalIndex(&smeta, signal_index);
2978     return Connection(QMetaObjectPrivate::connect(sender, signal_index, smeta,
2979                                        receiver, method_index,
2980                                        0, //FIXME, we could speed this connection up by computing the relative index
2981                                        type, types));
2982 }
2983
2984 /*! \internal
2985    Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
2986
2987     method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
2988
2989     the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection
2990  */
2991 QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
2992                                  int signal_index, const QMetaObject *smeta,
2993                                  const QObject *receiver, int method_index,
2994                                  const QMetaObject *rmeta, int type, int *types)
2995 {
2996     QObject *s = const_cast<QObject *>(sender);
2997     QObject *r = const_cast<QObject *>(receiver);
2998
2999     int method_offset = rmeta ? rmeta->methodOffset() : 0;
3000     Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
3001     QObjectPrivate::StaticMetaCallFunction callFunction =
3002         rmeta ? rmeta->d.static_metacall : 0;
3003
3004     QOrderedMutexLocker locker(signalSlotLock(sender),
3005                                signalSlotLock(receiver));
3006
3007     if (type & Qt::UniqueConnection) {
3008         QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3009         if (connectionLists && connectionLists->count() > signal_index) {
3010             const QObjectPrivate::Connection *c2 =
3011                 (*connectionLists)[signal_index].first;
3012
3013             int method_index_absolute = method_index + method_offset;
3014
3015             while (c2) {
3016                 if (c2->receiver == receiver && c2->method() == method_index_absolute)
3017                     return 0;
3018                 c2 = c2->nextConnectionList;
3019             }
3020         }
3021         type &= Qt::UniqueConnection - 1;
3022     }
3023
3024     QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
3025     c->sender = s;
3026     c->receiver = r;
3027     c->method_relative = method_index;
3028     c->method_offset = method_offset;
3029     c->connectionType = type;
3030     c->isSlotObject = false;
3031     c->argumentTypes.store(types);
3032     c->nextConnectionList = 0;
3033     c->callFunction = callFunction;
3034
3035     QObjectPrivate::get(s)->addConnection(signal_index, c.data());
3036
3037     locker.unlock();
3038     QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3039     if (smethod.isValid())
3040         s->connectNotify(smethod);
3041
3042     return c.take();
3043 }
3044
3045 /*!\internal
3046  */
3047 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
3048                              const QObject *receiver, int method_index)
3049 {
3050     const QMetaObject *smeta = sender->metaObject();
3051     signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3052     return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3053                                           receiver, method_index, 0);
3054 }
3055
3056 /*!\internal
3057
3058 Disconnect a single signal connection.  If QMetaObject::connect() has been called 
3059 multiple times for the same sender, signal_index, receiver and method_index only 
3060 one of these connections will be removed.
3061  */
3062 bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
3063                                 const QObject *receiver, int method_index)
3064 {
3065     const QMetaObject *smeta = sender->metaObject();
3066     signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3067     return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3068                                           receiver, method_index, 0,
3069                                           QMetaObjectPrivate::DisconnectOne);
3070 }
3071
3072 /*! \internal
3073     Helper function to remove the connection from the senders list and setting the receivers to 0
3074  */
3075 bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
3076                                           const QObject *receiver, int method_index, void **slot,
3077                                           QMutex *senderMutex, DisconnectType disconnectType)
3078 {
3079     bool success = false;
3080     while (c) {
3081         if (c->receiver
3082             && (receiver == 0 || (c->receiver == receiver
3083                            && (method_index < 0 || c->method() == method_index)
3084                            && (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
3085             bool needToUnlock = false;
3086             QMutex *receiverMutex = 0;
3087             if (!receiver) {
3088                 receiverMutex = signalSlotLock(c->receiver);
3089                 // need to relock this receiver and sender in the correct order
3090                 needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
3091             }
3092             if (c->receiver) {
3093                 *c->prev = c->next;
3094                 if (c->next)
3095                     c->next->prev = c->prev;
3096             }
3097
3098             if (needToUnlock)
3099                 receiverMutex->unlock();
3100
3101             c->receiver = 0;
3102
3103             success = true;
3104
3105             if (disconnectType == DisconnectOne)
3106                 return success;
3107         }
3108         c = c->nextConnectionList;
3109     }
3110     return success;
3111 }
3112
3113 /*! \internal
3114     Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3115  */
3116 bool QMetaObjectPrivate::disconnect(const QObject *sender,
3117                                     int signal_index, const QMetaObject *smeta,
3118                                     const QObject *receiver, int method_index, void **slot,
3119                                     DisconnectType disconnectType)
3120 {
3121     if (!sender)
3122         return false;
3123
3124     QObject *s = const_cast<QObject *>(sender);
3125
3126     QMutex *senderMutex = signalSlotLock(sender);
3127     QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
3128     QOrderedMutexLocker locker(senderMutex, receiverMutex);
3129
3130     QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3131     if (!connectionLists)
3132         return false;
3133
3134     // prevent incoming connections changing the connectionLists while unlocked
3135     ++connectionLists->inUse;
3136
3137     bool success = false;
3138     if (signal_index < 0) {
3139         // remove from all connection lists
3140         for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) {
3141             QObjectPrivate::Connection *c =
3142                 (*connectionLists)[sig_index].first;
3143             if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
3144                 success = true;
3145                 connectionLists->dirty = true;
3146             }
3147         }
3148     } else if (signal_index < connectionLists->count()) {
3149         QObjectPrivate::Connection *c =
3150             (*connectionLists)[signal_index].first;
3151         if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
3152             success = true;
3153             connectionLists->dirty = true;
3154         }
3155     }
3156
3157     --connectionLists->inUse;
3158     Q_ASSERT(connectionLists->inUse >= 0);
3159     if (connectionLists->orphaned && !connectionLists->inUse)
3160         delete connectionLists;
3161
3162     locker.unlock();
3163     if (success) {
3164         QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3165         if (smethod.isValid())
3166             s->disconnectNotify(smethod);
3167     }
3168
3169     return success;
3170 }
3171
3172 /*!
3173     \fn void QMetaObject::connectSlotsByName(QObject *object)
3174
3175     Searches recursively for all child objects of the given \a object, and connects
3176     matching signals from them to slots of \a object that follow the following form:
3177
3178     \snippet code/src_corelib_kernel_qobject.cpp 33
3179
3180     Let's assume our object has a child object of type QPushButton with
3181     the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
3182     button's \c{clicked()} signal would be:
3183
3184     \snippet code/src_corelib_kernel_qobject.cpp 34
3185
3186     \sa QObject::setObjectName()
3187  */
3188 void QMetaObject::connectSlotsByName(QObject *o)
3189 {
3190     if (!o)
3191         return;
3192     const QMetaObject *mo = o->metaObject();
3193     Q_ASSERT(mo);
3194     const QObjectList list = o->findChildren<QObject *>(QString());
3195     for (int i = 0; i < mo->methodCount(); ++i) {
3196         QByteArray slotSignature = mo->method(i).methodSignature();
3197         const char *slot = slotSignature.constData();
3198         Q_ASSERT(slot);
3199         if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
3200             continue;
3201         bool foundIt = false;
3202         for(int j = 0; j < list.count(); ++j) {
3203             const QObject *co = list.at(j);
3204             QByteArray objName = co->objectName().toLatin1();
3205             int len = objName.length();
3206             if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
3207                 continue;
3208             const QMetaObject *smeta;
3209             int sigIndex = co->d_func()->signalIndex(slot + len + 4, &smeta);
3210             if (sigIndex < 0) { // search for compatible signals
3211                 const QMetaObject *smo = co->metaObject();
3212                 int slotlen = qstrlen(slot + len + 4) - 1;
3213                 for (int k = 0; k < QMetaObjectPrivate::absoluteSignalCount(smo); ++k) {
3214                     QMetaMethod method = QMetaObjectPrivate::signal(smo, k);
3215                     if (!qstrncmp(method.methodSignature().constData(), slot + len + 4, slotlen)) {
3216                         smeta = method.enclosingMetaObject();
3217                         sigIndex = k;
3218                         break;
3219                     }
3220                 }
3221             }
3222             if (sigIndex < 0)
3223                 continue;
3224
3225             if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
3226                 foundIt = true;
3227                 break;
3228             }
3229         }
3230         if (foundIt) {
3231             // we found our slot, now skip all overloads
3232             while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
3233                   ++i;
3234         } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
3235             qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
3236         }
3237     }
3238 }
3239
3240 static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
3241 {
3242     const int *argumentTypes = c->argumentTypes.load();
3243     if (!argumentTypes && argumentTypes != &DIRECT_CONNECTION_ONLY) {
3244         QMetaMethod m = sender->metaObject()->method(signal);
3245         argumentTypes = queuedConnectionTypes(m.parameterTypes());
3246         if (!argumentTypes) // cannot queue arguments
3247             argumentTypes = &DIRECT_CONNECTION_ONLY;
3248         if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
3249             if (argumentTypes != &DIRECT_CONNECTION_ONLY)
3250                 delete [] argumentTypes;
3251             argumentTypes = c->argumentTypes.load();
3252         }
3253     }
3254     if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
3255         return;
3256     int nargs = 1; // include return type
3257     while (argumentTypes[nargs-1])
3258         ++nargs;
3259     int *types = (int *) malloc(nargs*sizeof(int));
3260     Q_CHECK_PTR(types);
3261     void **args = (void **) malloc(nargs*sizeof(void *));
3262     Q_CHECK_PTR(args);
3263     types[0] = 0; // return type
3264     args[0] = 0; // return value
3265     for (int n = 1; n < nargs; ++n)
3266         args[n] = QMetaType::create((types[n] = argumentTypes[n-1]), argv[n]);
3267     QMetaCallEvent *ev = c->isSlotObject ?
3268         new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
3269         new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
3270     QCoreApplication::postEvent(c->receiver, ev);
3271 }
3272
3273 /*!\internal
3274  */
3275 void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
3276                            void **argv)
3277 {
3278     int signalOffset;
3279     int methodOffset;
3280     computeOffsets(m, &signalOffset, &methodOffset);
3281     activate(sender, methodOffset, signalOffset, local_signal_index, argv);
3282 }
3283
3284 /*!\internal
3285  */
3286 void QMetaObject::activate(QObject *sender, int methodOffset, int signalOffset, int local_signal_index,
3287                            void **argv)
3288 {
3289     int signal_index = signalOffset + local_signal_index;
3290
3291     if (sender->d_func()->declarativeData && QAbstractDeclarativeData::signalEmitted)
3292         QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender, 
3293                                                 methodOffset + local_signal_index, argv);
3294
3295     if (!sender->d_func()->isSignalConnected(signal_index))
3296         return; // nothing connected to these signals, and no spy
3297
3298     if (sender->d_func()->blockSig)
3299         return;
3300
3301     int signal_absolute_index = methodOffset + local_signal_index;
3302
3303     void *empty_argv[] = { 0 };
3304     if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
3305         qt_signal_spy_callback_set.signal_begin_callback(sender, signal_absolute_index,
3306                                                          argv ? argv : empty_argv);
3307     }
3308
3309     Qt::HANDLE currentThreadId = QThread::currentThreadId();
3310
3311     {
3312     QMutexLocker locker(signalSlotLock(sender));
3313     struct ConnectionListsRef {
3314         QObjectConnectionListVector *connectionLists;
3315         ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists)
3316         {
3317             if (connectionLists)
3318                 ++connectionLists->inUse;
3319         }
3320         ~ConnectionListsRef()
3321         {
3322             if (!connectionLists)
3323                 return;
3324
3325             --connectionLists->inUse;
3326             Q_ASSERT(connectionLists->inUse >= 0);
3327             if (connectionLists->orphaned) {
3328                 if (!connectionLists->inUse)
3329                     delete connectionLists;
3330             }
3331         }
3332
3333         QObjectConnectionListVector *operator->() const { return connectionLists; }
3334     };
3335     ConnectionListsRef connectionLists = sender->d_func()->connectionLists;
3336     if (!connectionLists.connectionLists) {
3337         locker.unlock();
3338         if (qt_signal_spy_callback_set.signal_end_callback != 0)
3339             qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3340         return;
3341     }
3342
3343     const QObjectPrivate::ConnectionList *list;
3344     if (signal_index < connectionLists->count())
3345         list = &connectionLists->at(signal_index);
3346     else
3347         list = &connectionLists->allsignals;
3348
3349     do {
3350         QObjectPrivate::Connection *c = list->first;
3351         if (!c) continue;
3352         // We need to check against last here to ensure that signals added
3353         // during the signal emission are not emitted in this emission.
3354         QObjectPrivate::Connection *last = list->last;
3355
3356         do {
3357             if (!c->receiver)
3358                 continue;
3359
3360             QObject * const receiver = c->receiver;
3361             const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
3362
3363             // determine if this connection should be sent immediately or
3364             // put into the event queue
3365             if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
3366                 || (c->connectionType == Qt::QueuedConnection)) {
3367                 queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
3368                 continue;
3369 #ifndef QT_NO_THREAD
3370             } else if (c->connectionType == Qt::BlockingQueuedConnection) {
3371                 locker.unlock();
3372                 if (receiverInSameThread) {
3373                     qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
3374                     "Sender is %s(%p), receiver is %s(%p)",
3375                     sender->metaObject()->className(), sender,
3376                     receiver->metaObject()->className(), receiver);
3377                 }
3378                 QSemaphore semaphore;
3379                 QMetaCallEvent *ev = c->isSlotObject ?
3380                     new QMetaCallEvent(c->slotObj, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore) :
3381                     new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore);
3382                 QCoreApplication::postEvent(receiver, ev);
3383                 semaphore.acquire();
3384                 locker.relock();
3385                 continue;
3386 #endif
3387             }
3388
3389             QConnectionSenderSwitcher sw;
3390
3391             if (receiverInSameThread) {
3392                 sw.switchSender(receiver, sender, signal_absolute_index);
3393             }
3394             const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
3395             const int method_relative = c->method_relative;
3396             if (c->isSlotObject) {
3397                 QExplicitlySharedDataPointer<QObject::QSlotObjectBase> obj(c->slotObj);
3398                 locker.unlock();
3399                 obj->call(receiver, argv ? argv : empty_argv);
3400                 locker.relock();
3401             } else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
3402                 //we compare the vtable to make sure we are not in the destructor of the object.
3403                 locker.unlock();
3404                 if (qt_signal_spy_callback_set.slot_begin_callback != 0)
3405                     qt_signal_spy_callback_set.slot_begin_callback(receiver, c->method(), argv ? argv : empty_argv);
3406
3407                 callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
3408
3409                 if (qt_signal_spy_callback_set.slot_end_callback != 0)
3410                     qt_signal_spy_callback_set.slot_end_callback(receiver, c->method());
3411                 locker.relock();
3412             } else {
3413                 const int method = method_relative + c->method_offset;
3414                 locker.unlock();
3415
3416                 if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
3417                     qt_signal_spy_callback_set.slot_begin_callback(receiver,
3418                                                                 method,
3419                                                                 argv ? argv : empty_argv);
3420                 }
3421
3422                 metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
3423
3424                 if (qt_signal_spy_callback_set.slot_end_callback != 0)
3425                     qt_signal_spy_callback_set.slot_end_callback(receiver, method);
3426
3427                 locker.relock();
3428             }
3429
3430             if (connectionLists->orphaned)
3431                 break;
3432         } while (c != last && (c = c->nextConnectionList) != 0);
3433
3434         if (connectionLists->orphaned)
3435             break;
3436     } while (list != &connectionLists->allsignals &&
3437         //start over for all signals;
3438         ((list = &connectionLists->allsignals), true));
3439
3440     }
3441
3442     if (qt_signal_spy_callback_set.signal_end_callback != 0)
3443         qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3444
3445 }
3446
3447 /*!\internal
3448    signal_index comes from indexOfMethod()
3449 */
3450 void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
3451 {
3452     const QMetaObject *mo = sender->metaObject();
3453     while (mo->methodOffset() > signal_index)
3454         mo = mo->superClass();
3455     activate(sender, mo, signal_index - mo->methodOffset(), argv);
3456 }
3457
3458 /*! \internal
3459     Implementation of QObject::senderSignalIndex()
3460 */
3461 int QObjectPrivate::senderSignalIndex() const
3462 {
3463     Q_Q(const QObject);
3464     QMutexLocker locker(signalSlotLock(q));
3465     if (!currentSender)
3466         return -1;
3467
3468     for (QObjectPrivate::Connection *c = senders; c; c = c->next) {
3469         if (c->sender == currentSender->sender)
3470             return currentSender->signal;
3471     }
3472
3473     return -1;
3474 }
3475
3476 /*! \internal
3477     Returns the signal index used in the internal connectionLists vector.
3478
3479     It is different from QMetaObject::indexOfSignal():  indexOfSignal is the same as indexOfMethod
3480     while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
3481
3482     If \a meta is not 0, it is set to the meta-object where the signal was found.
3483 */
3484 int QObjectPrivate::signalIndex(const char *signalName,
3485                                 const QMetaObject **meta) const
3486 {
3487     Q_Q(const QObject);
3488     const QMetaObject *base = q->metaObject();
3489     Q_ASSERT(QMetaObjectPrivate::get(base)->revision >= 7);
3490     QArgumentTypeArray types;
3491     QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signalName, types);
3492     int relative_index = QMetaObjectPrivate::indexOfSignalRelative(
3493             &base, name, types.size(), types.constData());
3494     if (relative_index < 0)
3495         return relative_index;
3496     relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
3497     int signalOffset, methodOffset;
3498     computeOffsets(base, &signalOffset, &methodOffset);
3499     if (meta)
3500         *meta = base;
3501     return relative_index + signalOffset;
3502 }
3503
3504 /*****************************************************************************
3505   Properties
3506  *****************************************************************************/
3507
3508 #ifndef QT_NO_PROPERTIES
3509
3510 /*!
3511   Sets the value of the object's \a name property to \a value.
3512
3513   If the property is defined in the class using Q_PROPERTY then
3514   true is returned on success and false otherwise. If the property
3515   is not defined using Q_PROPERTY, and therefore not listed in the
3516   meta-object, it is added as a dynamic property and false is returned.
3517
3518   Information about all available properties is provided through the
3519   metaObject() and dynamicPropertyNames().
3520
3521   Dynamic properties can be queried again using property() and can be
3522   removed by setting the property value to an invalid QVariant.
3523   Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent
3524   to be sent to the object.
3525
3526   \b{Note:} Dynamic properties starting with "_q_" are reserved for internal
3527   purposes.
3528
3529   \sa property(), metaObject(), dynamicPropertyNames()
3530 */
3531 bool QObject::setProperty(const char *name, const QVariant &value)
3532 {
3533     Q_D(QObject);
3534     const QMetaObject* meta = metaObject();
3535     if (!name || !meta)
3536         return false;
3537
3538     int id = meta->indexOfProperty(name);
3539     if (id < 0) {
3540         if (!d->extraData)
3541             d->extraData = new QObjectPrivate::ExtraData;
3542
3543         const int idx = d->extraData->propertyNames.indexOf(name);
3544
3545         if (!value.isValid()) {
3546             if (idx == -1)
3547                 return false;
3548             d->extraData->propertyNames.removeAt(idx);
3549             d->extraData->propertyValues.removeAt(idx);
3550         } else {
3551             if (idx == -1) {
3552                 d->extraData->propertyNames.append(name);
3553                 d->extraData->propertyValues.append(value);
3554             } else {
3555                 d->extraData->propertyValues[idx] = value;
3556             }
3557         }
3558
3559         QDynamicPropertyChangeEvent ev(name);
3560         QCoreApplication::sendEvent(this, &ev);
3561
3562         return false;
3563     }
3564     QMetaProperty p = meta->property(id);
3565 #ifndef QT_NO_DEBUG
3566     if (!p.isWritable())
3567         qWarning("%s::setProperty: Property \"%s\" invalid,"
3568                  " read-only or does not exist", metaObject()->className(), name);
3569 #endif
3570     return p.write(this, value);
3571 }
3572
3573 /*!
3574   Returns the value of the object's \a name property.
3575
3576   If no such property exists, the returned variant is invalid.
3577
3578   Information about all available properties is provided through the
3579   metaObject() and dynamicPropertyNames().
3580
3581   \sa setProperty(), QVariant::isValid(), metaObject(), dynamicPropertyNames()
3582 */
3583 QVariant QObject::property(const char *name) const
3584 {
3585     Q_D(const QObject);
3586     const QMetaObject* meta = metaObject();
3587     if (!name || !meta)
3588         return QVariant();
3589
3590     int id = meta->indexOfProperty(name);
3591     if (id < 0) {
3592         if (!d->extraData)
3593             return QVariant();
3594         const int i = d->extraData->propertyNames.indexOf(name);
3595         return d->extraData->propertyValues.value(i);
3596     }
3597     QMetaProperty p = meta->property(id);
3598 #ifndef QT_NO_DEBUG
3599     if (!p.isReadable())
3600         qWarning("%s::property: Property \"%s\" invalid or does not exist",
3601                  metaObject()->className(), name);
3602 #endif
3603     return p.read(this);
3604 }
3605
3606 /*!
3607     \since 4.2
3608
3609     Returns the names of all properties that were dynamically added to
3610     the object using setProperty().
3611 */
3612 QList<QByteArray> QObject::dynamicPropertyNames() const
3613 {
3614     Q_D(const QObject);
3615     if (d->extraData)
3616         return d->extraData->propertyNames;
3617     return QList<QByteArray>();
3618 }
3619
3620 #endif // QT_NO_PROPERTIES
3621
3622
3623 /*****************************************************************************
3624   QObject debugging output routines.
3625  *****************************************************************************/
3626
3627 static void dumpRecursive(int level, QObject *object)
3628 {
3629 #if defined(QT_DEBUG)
3630     if (object) {
3631         QByteArray buf;
3632         buf.fill(' ', level / 2 * 8);
3633         if (level % 2)
3634             buf += "    ";
3635         QString name = object->objectName();
3636         QString flags = QLatin1String("");
3637 #if 0
3638         if (qApp->focusWidget() == object)
3639             flags += 'F';
3640         if (object->isWidgetType()) {
3641             QWidget * w = (QWidget *)object;
3642             if (w->isVisible()) {
3643                 QString t("<%1,%2,%3,%4>");
3644                 flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height());
3645             } else {
3646                 flags += 'I';
3647             }
3648         }
3649 #endif
3650         qDebug("%s%s::%s %s", (const char*)buf, object->metaObject()->className(), name.toLocal8Bit().data(),
3651                flags.toLatin1().data());
3652         QObjectList children = object->children();
3653         if (!children.isEmpty()) {
3654             for (int i = 0; i < children.size(); ++i)
3655                 dumpRecursive(level+1, children.at(i));
3656         }
3657     }
3658 #else
3659     Q_UNUSED(level)
3660         Q_UNUSED(object)
3661 #endif
3662 }
3663
3664 /*!
3665     Dumps a tree of children to the debug output.
3666
3667     This function is useful for debugging, but does nothing if the
3668     library has been compiled in release mode (i.e. without debugging
3669     information).
3670
3671     \sa dumpObjectInfo()
3672 */
3673
3674 void QObject::dumpObjectTree()
3675 {
3676     dumpRecursive(0, this);
3677 }
3678
3679 /*!
3680     Dumps information about signal connections, etc. for this object
3681     to the debug output.
3682
3683     This function is useful for debugging, but does nothing if the
3684     library has been compiled in release mode (i.e. without debugging
3685     information).
3686
3687     \sa dumpObjectTree()
3688 */
3689
3690 void QObject::dumpObjectInfo()
3691 {
3692 #if defined(QT_DEBUG)
3693     qDebug("OBJECT %s::%s", metaObject()->className(),
3694            objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data());
3695
3696     Q_D(QObject);
3697     QMutexLocker locker(signalSlotLock(this));
3698
3699     // first, look for connections where this object is the sender
3700     qDebug("  SIGNALS OUT");
3701
3702     if (d->connectionLists) {
3703         for (int signal_index = 0; signal_index < d->connectionLists->count(); ++signal_index) {
3704             const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index);
3705             qDebug("        signal: %s", signal.methodSignature().constData());
3706
3707             // receivers
3708             const QObjectPrivate::Connection *c =
3709                 d->connectionLists->at(signal_index).first;
3710             while (c) {
3711                 if (!c->receiver) {
3712                     qDebug("          <Disconnected receiver>");
3713                     c = c->nextConnectionList;
3714                     continue;
3715                 }
3716                 const QMetaObject *receiverMetaObject = c->receiver->metaObject();
3717                 const QMetaMethod method = receiverMetaObject->method(c->method());
3718                 qDebug("          --> %s::%s %s",
3719                        receiverMetaObject->className(),
3720                        c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
3721                        method.methodSignature().constData());
3722                 c = c->nextConnectionList;
3723             }
3724         }
3725     } else {
3726         qDebug( "        <None>" );
3727     }
3728
3729     // now look for connections where this object is the receiver
3730     qDebug("  SIGNALS IN");
3731
3732     if (d->senders) {
3733         for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
3734             const QMetaMethod slot = metaObject()->method(s->method());
3735             qDebug("          <-- %s::%s  %s",
3736                    s->sender->metaObject()->className(),
3737                    s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
3738                    slot.methodSignature().constData());
3739         }
3740     } else {
3741         qDebug("        <None>");
3742     }
3743 #endif
3744 }
3745
3746 #ifndef QT_NO_USERDATA
3747 /*!\internal
3748  */
3749 uint QObject::registerUserData()
3750 {
3751     static int user_data_registration = 0;
3752     return user_data_registration++;
3753 }
3754
3755 /*!\internal
3756  */
3757 QObjectUserData::~QObjectUserData()
3758 {
3759 }
3760
3761 /*!\internal
3762  */
3763 void QObject::setUserData(uint id, QObjectUserData* data)
3764 {
3765     Q_D(QObject);
3766     if (!d->extraData)
3767         d->extraData = new QObjectPrivate::ExtraData;
3768
3769     if (d->extraData->userData.size() <= (int) id)
3770         d->extraData->userData.resize((int) id + 1);
3771     d->extraData->userData[id] = data;
3772 }
3773
3774 /*!\internal
3775  */
3776 QObjectUserData* QObject::userData(uint id) const
3777 {
3778     Q_D(const QObject);
3779     if (!d->extraData)
3780         return 0;
3781     if ((int)id < d->extraData->userData.size())
3782         return d->extraData->userData.at(id);
3783     return 0;
3784 }
3785
3786 #endif // QT_NO_USERDATA
3787
3788
3789 #ifndef QT_NO_DEBUG_STREAM
3790 QDebug operator<<(QDebug dbg, const QObject *o) {
3791     if (!o)
3792         return dbg << "QObject(0x0) ";
3793     dbg.nospace() << o->metaObject()->className() << '(' << (void *)o;
3794     if (!o->objectName().isEmpty())
3795         dbg << ", name = " << o->objectName();
3796     dbg << ')';
3797     return dbg.space();
3798 }
3799 #endif
3800
3801 /*!
3802     \macro Q_CLASSINFO(Name, Value)
3803     \relates QObject
3804
3805     This macro associates extra information to the class, which is
3806     available using QObject::metaObject(). Except for the ActiveQt
3807     extension, Qt doesn't use this information.
3808
3809     The extra information takes the form of a \a Name string and a \a
3810     Value literal string.
3811
3812     Example:
3813
3814     \snippet code/src_corelib_kernel_qobject.cpp 35
3815
3816     \sa QMetaObject::classInfo()
3817 */
3818
3819 /*!
3820     \macro Q_INTERFACES(...)
3821     \relates QObject
3822
3823     This macro tells Qt which interfaces the class implements. This
3824     is used when implementing plugins.
3825
3826     Example:
3827
3828     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
3829     \dots
3830     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 3
3831
3832     See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint
3833     Basic Tools} example for details.
3834
3835     \sa Q_DECLARE_INTERFACE(), Q_EXPORT_PLUGIN2(), {How to Create Qt Plugins}
3836 */
3837
3838 /*!
3839     \macro Q_PROPERTY(...)
3840     \relates QObject
3841
3842     This macro is used for declaring properties in classes that
3843     inherit QObject. Properties behave like class data members, but
3844     they have additional features accessible through the \l
3845     {Meta-Object System}.
3846
3847     \snippet code/src_corelib_kernel_qobject.cpp 36
3848
3849     The property name and type and the \c READ function are required.
3850     The type can be any type supported by QVariant, or it can be a
3851     user-defined type.  The other items are optional, but a \c WRITE
3852     function is common.  The attributes default to true except \c USER,
3853     which defaults to false.
3854
3855     For example:
3856
3857     \snippet code/src_corelib_kernel_qobject.cpp 37
3858
3859     For more details about how to use this macro, and a more detailed
3860     example of its use, see the discussion on \l {Qt's Property System}.
3861
3862     \sa {Qt's Property System}
3863 */
3864
3865 /*!
3866     \macro Q_ENUMS(...)
3867     \relates QObject
3868
3869     This macro registers one or several enum types to the meta-object
3870     system.
3871
3872     For example:
3873
3874     \snippet code/src_corelib_kernel_qobject.cpp 38
3875
3876     If you want to register an enum that is declared in another class,
3877     the enum must be fully qualified with the name of the class
3878     defining it. In addition, the class \e defining the enum has to
3879     inherit QObject as well as declare the enum using Q_ENUMS().
3880
3881     \sa {Qt's Property System}
3882 */
3883
3884 /*!
3885     \macro Q_FLAGS(...)
3886     \relates QObject
3887
3888     This macro registers one or several \l{QFlags}{flags types} to the
3889     meta-object system. It is typically used in a class definition to declare
3890     that values of a given enum can be used as flags and combined using the
3891     bitwise OR operator.
3892
3893     For example, in QLibrary, the \l{QLibrary::LoadHints}{LoadHints} flag is
3894     declared in the following way:
3895
3896     \snippet code/src_corelib_kernel_qobject.cpp 39a
3897
3898     The declaration of the flags themselves is performed in the public section
3899     of the QLibrary class itself, using the \l Q_DECLARE_FLAGS() macro:
3900
3901     \snippet code/src_corelib_kernel_qobject.cpp 39b
3902
3903     \note This macro takes care of registering individual flag values
3904     with the meta-object system, so it is unnecessary to use Q_ENUMS()
3905     in addition to this macro.
3906
3907     \sa {Qt's Property System}
3908 */
3909
3910 /*!
3911     \macro Q_OBJECT
3912     \relates QObject
3913
3914     The Q_OBJECT macro must appear in the private section of a class
3915     definition that declares its own signals and slots or that uses
3916     other services provided by Qt's meta-object system.
3917
3918     For example:
3919
3920     \snippet signalsandslots/signalsandslots.h 1
3921     \codeline
3922     \snippet signalsandslots/signalsandslots.h 2
3923     \snippet signalsandslots/signalsandslots.h 3
3924
3925     \note This macro requires the class to be a subclass of QObject. Use
3926     Q_GADGET instead of Q_OBJECT to enable the meta object system's support
3927     for enums in a class that is not a QObject subclass. Q_GADGET makes a
3928     class member, \c{staticMetaObject}, available.
3929     \c{staticMetaObject} is of type QMetaObject and provides access to the
3930     enums declared with Q_ENUMS.
3931     Q_GADGET is provided only for C++.
3932
3933     \sa {Meta-Object System}, {Signals and Slots}, {Qt's Property System}
3934 */
3935
3936 /*!
3937     \macro Q_SIGNALS
3938     \relates QObject
3939
3940     Use this macro to replace the \c signals keyword in class
3941     declarations, when you want to use Qt Signals and Slots with a
3942     \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3943
3944     The macro is normally used when \c no_keywords is specified with
3945     the \c CONFIG variable in the \c .pro file, but it can be used
3946     even when \c no_keywords is \e not specified.
3947 */
3948
3949 /*!
3950     \macro Q_SIGNAL
3951     \relates QObject
3952
3953     This is an additional macro that allows you to mark a single
3954     function as a signal. It can be quite useful, especially when you
3955     use a 3rd-party source code parser which doesn't understand a \c
3956     signals or \c Q_SIGNALS groups.
3957
3958     Use this macro to replace the \c signals keyword in class
3959     declarations, when you want to use Qt Signals and Slots with a
3960     \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3961
3962     The macro is normally used when \c no_keywords is specified with
3963     the \c CONFIG variable in the \c .pro file, but it can be used
3964     even when \c no_keywords is \e not specified.
3965 */
3966
3967 /*!
3968     \macro Q_SLOTS
3969     \relates QObject
3970
3971     Use this macro to replace the \c slots keyword in class
3972     declarations, when you want to use Qt Signals and Slots with a
3973     \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3974
3975     The macro is normally used when \c no_keywords is specified with
3976     the \c CONFIG variable in the \c .pro file, but it can be used
3977     even when \c no_keywords is \e not specified.
3978 */
3979
3980 /*!
3981     \macro Q_SLOT
3982     \relates QObject
3983
3984     This is an additional macro that allows you to mark a single
3985     function as a slot. It can be quite useful, especially when you
3986     use a 3rd-party source code parser which doesn't understand a \c
3987     slots or \c Q_SLOTS groups.
3988
3989     Use this macro to replace the \c slots keyword in class
3990     declarations, when you want to use Qt Signals and Slots with a
3991     \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3992
3993     The macro is normally used when \c no_keywords is specified with
3994     the \c CONFIG variable in the \c .pro file, but it can be used
3995     even when \c no_keywords is \e not specified.
3996 */
3997
3998 /*!
3999     \macro Q_EMIT
4000     \relates QObject
4001
4002     Use this macro to replace the \c emit keyword for emitting
4003     signals, when you want to use Qt Signals and Slots with a
4004     \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
4005
4006     The macro is normally used when \c no_keywords is specified with
4007     the \c CONFIG variable in the \c .pro file, but it can be used
4008     even when \c no_keywords is \e not specified.
4009 */
4010
4011 /*!
4012     \macro Q_INVOKABLE
4013     \relates QObject
4014
4015     Apply this macro to definitions of member functions to allow them to
4016     be invoked via the meta-object system. The macro is written before
4017     the return type, as shown in the following example:
4018
4019     \snippet qmetaobject-invokable/window.h Window class with invokable method
4020
4021     The \c invokableMethod() function is marked up using Q_INVOKABLE, causing
4022     it to be registered with the meta-object system and enabling it to be
4023     invoked using QMetaObject::invokeMethod().
4024     Since \c normalMethod() function is not registered in this way, it cannot
4025     be invoked using QMetaObject::invokeMethod().
4026 */
4027
4028 /*!
4029     \typedef QObjectList
4030     \relates QObject
4031
4032     Synonym for QList<QObject *>.
4033 */
4034
4035 void qDeleteInEventHandler(QObject *o)
4036 {
4037     delete o;
4038 }
4039
4040 /*!
4041     \fn QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
4042     \overload connect()
4043     \threadsafe
4044
4045     Creates a connection of the given \a type from the \a signal in
4046     the \a sender object to the \a method in the \a receiver object.
4047     Returns a handle to the connection that can be used to disconnect
4048     it later.
4049
4050     The signal must be a function declared as a signal in the header.
4051     The slot function can be any member function that can be connected
4052     to the signal.
4053     A slot can be connected to a given signal if the signal has at
4054     least as many arguments as the slot, and there is an implicit
4055     conversion between the types of the corresponding arguments in the
4056     signal and the slot.
4057
4058     Example:
4059
4060     \snippet code/src_corelib_kernel_qobject.cpp 44
4061
4062     This example ensures that the label always displays the current
4063     line edit text.
4064
4065     A signal can be connected to many slots and signals. Many signals
4066     can be connected to one slot.
4067
4068     If a signal is connected to several slots, the slots are activated
4069     in the same order as the order the connection was made, when the
4070     signal is emitted
4071
4072     The function returns an handle to a connection if it successfully
4073     connects the signal to the slot. The Connection handle will be invalid
4074     if it cannot create the connection, for example, if QObject is unable
4075     to verify the existence of \a signal (if it was not declared as a signal)
4076     You can check if the QMetaObject::Connection is valid by casting it to a bool.
4077
4078     By default, a signal is emitted for every connection you make;
4079     two signals are emitted for duplicate connections. You can break
4080     all of these connections with a single disconnect() call.
4081     If you pass the Qt::UniqueConnection \a type, the connection will only
4082     be made if it is not a duplicate. If there is already a duplicate
4083     (exact same signal to the exact same slot on the same objects),
4084     the connection will fail and connect will return an invalid QMetaObject::Connection.
4085
4086     The optional \a type parameter describes the type of connection
4087     to establish. In particular, it determines whether a particular
4088     signal is delivered to a slot immediately or queued for delivery
4089     at a later time. If the signal is queued, the parameters must be
4090     of types that are known to Qt's meta-object system, because Qt
4091     needs to copy the arguments to store them in an event behind the
4092     scenes. If you try to use a queued connection and get the error
4093     message
4094
4095     \snippet code/src_corelib_kernel_qobject.cpp 25
4096
4097     make sure to declare the argument type with Q_DECLARE_METATYPE
4098  */
4099
4100
4101 /*!
4102     \fn QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
4103
4104     \threadsafe
4105     \overload connect()
4106
4107     Creates a connection of the given \a type from the \a signal in
4108     the \a sender object to the \a functor and returns a handle to the connection
4109
4110     The signal must be a function declared as a signal in the header.
4111     The slot function can be any function or functor that can be connected
4112     to the signal.
4113     A function can be connected to a given signal if the signal as at
4114     least as many argument as the slot. A functor can be connected to a signal
4115     if they have exactly the same number of arguments. There must exist implicit
4116     conversion between the types of the corresponding arguments in the
4117     signal and the slot.
4118
4119     Example:
4120
4121     \snippet code/src_corelib_kernel_qobject.cpp 45
4122
4123     If your compiler support C++11 lambda expressions, you can use them:
4124
4125     \snippet code/src_corelib_kernel_qobject.cpp 46
4126
4127     The connection will automatically disconnect if the sender is destroyed.
4128  */
4129
4130 /** \internal
4131
4132     Implementation of the template version of connect
4133
4134     \a sender is the sender object
4135     \a signal is a pointer to a pointer to a member signal of the sender
4136     \a receiver is the receiver object, may not be null, will be equal to sender when
4137                 connecting to a static function or a functor
4138     \a slot a pointer only used when using Qt::UniqueConnection
4139     \a type the Qt::ConnctionType passed as argument to connect
4140     \a types an array of integer with the metatype id of the parametter of the signal
4141              to be used with queued connection
4142              must stay valid at least for the whole time of the connection, this function
4143              do not take ownership. typically static data.
4144              If null, then the types will be computed when the signal is emit in a queued
4145              connection from the types from the signature.
4146     \a senderMetaObject is the metaobject used to lookup the signal, the signal must be in
4147                         this metaobject
4148  */
4149 QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal,
4150                                              const QObject *receiver, void **slot,
4151                                              QObject::QSlotObjectBase *slotObj, Qt::ConnectionType type,
4152                                              const int *types, const QMetaObject *senderMetaObject)
4153 {
4154     if (!sender || !signal || !slotObj || !senderMetaObject) {
4155         qWarning("QObject::connect: invalid null parametter");
4156         if (slotObj && !slotObj->ref.deref())
4157             delete slotObj;
4158         return QMetaObject::Connection();
4159     }
4160     int signal_index = -1;
4161     void *args[] = { &signal_index, signal };
4162     senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
4163     if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
4164         qWarning("QObject::connect: signal not found in %s", senderMetaObject->className());
4165         if (!slotObj->ref.deref())
4166             delete slotObj;
4167         return QMetaObject::Connection(0);
4168     }
4169     int signalOffset, methodOffset;
4170     computeOffsets(senderMetaObject, &signalOffset, &methodOffset);
4171     signal_index += signalOffset;
4172
4173     QObject *s = const_cast<QObject *>(sender);
4174     QObject *r = const_cast<QObject *>(receiver);
4175
4176     QOrderedMutexLocker locker(signalSlotLock(sender),
4177                                signalSlotLock(receiver));
4178
4179     if (type & Qt::UniqueConnection) {
4180         QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
4181         if (connectionLists && connectionLists->count() > signal_index) {
4182             const QObjectPrivate::Connection *c2 =
4183                 (*connectionLists)[signal_index].first;
4184
4185             while (c2) {
4186                 if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
4187                     if (!slotObj->ref.deref())
4188                         delete slotObj;
4189                     return QMetaObject::Connection();
4190                 }
4191                 c2 = c2->nextConnectionList;
4192             }
4193         }
4194         type = static_cast<Qt::ConnectionType>(type ^ Qt::UniqueConnection);
4195     }
4196
4197     QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
4198     c->sender = s;
4199     c->receiver = r;
4200     c->slotObj = slotObj;
4201     c->connectionType = type;
4202     c->isSlotObject = true;
4203     if (types) {
4204         c->argumentTypes.store(types);
4205         c->ownArgumentTypes = false;
4206     }
4207
4208     QObjectPrivate::get(s)->addConnection(signal_index, c.data());
4209     QMetaObject::Connection ret(c.take());
4210     locker.unlock();
4211
4212     QMetaMethod method = QMetaObjectPrivate::signal(senderMetaObject, signal_index);
4213     Q_ASSERT(method.isValid());
4214     s->connectNotify(method);
4215
4216     return ret;
4217 }
4218
4219 /*!
4220     Disconnect a connection.
4221
4222     If the \a connection is invalid or has already been disconnected, do nothing
4223     and return false.
4224
4225    \sa connect()
4226  */
4227 bool QObject::disconnect(const QMetaObject::Connection &connection)
4228 {
4229     QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(connection.d_ptr);
4230
4231     if (!c || !c->receiver)
4232         return false;
4233
4234     QMutex *senderMutex = signalSlotLock(c->sender);
4235     QMutex *receiverMutex = signalSlotLock(c->receiver);
4236     QOrderedMutexLocker locker(senderMutex, receiverMutex);
4237
4238     QObjectConnectionListVector *connectionLists = QObjectPrivate::get(c->sender)->connectionLists;
4239     Q_ASSERT(connectionLists);
4240     connectionLists->dirty = true;
4241
4242     *c->prev = c->next;
4243     if (c->next)
4244         c->next->prev = c->prev;
4245     c->receiver = 0;
4246     // disconnectNotify() not called (the signal index is unknown).
4247
4248     return true;
4249 }
4250
4251 /*! \fn bool QObject::disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
4252     \overload diconnect()
4253     \threadsafe
4254
4255     Disconnects \a signal in object \a sender from \a method in object
4256     \a receiver. Returns true if the connection is successfully broken;
4257     otherwise returns false.
4258
4259     A signal-slot connection is removed when either of the objects
4260     involved are destroyed.
4261
4262     disconnect() is typically used in three ways, as the following
4263     examples demonstrate.
4264     \list 1
4265     \li Disconnect everything connected to an object's signals:
4266
4267        \snippet code/src_corelib_kernel_qobject.cpp 26
4268
4269     \li Disconnect everything connected to a specific signal:
4270
4271        \snippet code/src_corelib_kernel_qobject.cpp 47
4272
4273     \li Disconnect a specific receiver:
4274
4275        \snippet code/src_corelib_kernel_qobject.cpp 30
4276
4277     \li Disconnect a connection from one specific signal to a specific slot:
4278
4279        \snippet code/src_corelib_kernel_qobject.cpp 48
4280
4281
4282     \endlist
4283
4284     0 may be used as a wildcard, meaning "any signal", "any receiving
4285     object", or "any slot in the receiving object", respectively.
4286
4287     The \a sender may never be 0. (You cannot disconnect signals from
4288     more than one object in a single call.)
4289
4290     If \a signal is 0, it disconnects \a receiver and \a method from
4291     any signal. If not, only the specified signal is disconnected.
4292
4293     If \a receiver is 0, it disconnects anything connected to \a
4294     signal. If not, slots in objects other than \a receiver are not
4295     disconnected.
4296
4297     If \a method is 0, it disconnects anything that is connected to \a
4298     receiver. If not, only slots named \a method will be disconnected,
4299     and all other slots are left alone. The \a method must be 0 if \a
4300     receiver is left out, so you cannot disconnect a
4301     specifically-named slot on all objects.
4302
4303     \note It is not possible to use this overload to diconnect signals
4304     connected to functors or lambda expressions. That is because it is not
4305     possible to compare them. Instead, use the olverload that take a
4306     QMetaObject::Connection
4307
4308     \sa connect()
4309 */
4310
4311 bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot, const QMetaObject *senderMetaObject)
4312 {
4313     if (sender == 0 || (receiver == 0 && slot != 0)) {
4314         qWarning("QObject::disconnect: Unexpected null parameter");
4315         return false;
4316     }
4317
4318     int signal_index = -1;
4319     if (signal) {
4320         void *args[] = { &signal_index, signal };
4321         senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
4322         if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
4323             qWarning("QObject::disconnect: signal not found in %s", senderMetaObject->className());
4324             return false;
4325         }
4326         int signalOffset, methodOffset;
4327         computeOffsets(senderMetaObject, &signalOffset, &methodOffset);
4328         signal_index += signalOffset;
4329     }
4330
4331     return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, receiver, -1, slot);
4332 }
4333
4334 /*! \class QMetaObject::Connection
4335      Represents a handle to a signal-slot connection.
4336      It can be used to disconnect that connection, or check if
4337      the connection was successful
4338
4339      \sa QObject::disconnect
4340  */
4341
4342 /*!
4343     Create a copy of the handle to the connection
4344  */
4345 QMetaObject::Connection::Connection(const QMetaObject::Connection &other) : d_ptr(other.d_ptr)
4346 {
4347     if (d_ptr)
4348         static_cast<QObjectPrivate::Connection *>(d_ptr)->ref();
4349 }
4350
4351 QMetaObject::Connection& QMetaObject::Connection::operator=(const QMetaObject::Connection& other)
4352 {
4353     if (other.d_ptr != d_ptr) {
4354         if (d_ptr)
4355             static_cast<QObjectPrivate::Connection *>(d_ptr)->deref();
4356         d_ptr = other.d_ptr;
4357         if (other.d_ptr)
4358             static_cast<QObjectPrivate::Connection *>(other.d_ptr)->ref();
4359     }
4360     return *this;
4361 }
4362
4363 QMetaObject::Connection::Connection() : d_ptr(0) {}
4364
4365 QMetaObject::Connection::~Connection()
4366 {
4367     if (d_ptr)
4368         static_cast<QObjectPrivate::Connection *>(d_ptr)->deref();
4369 }
4370
4371 /*!
4372     \fn QMetaObject::Connection::operator bool() const
4373
4374     Returns true if the connection is valid.
4375
4376     The connection is valid if the call to QObject::connect succeeded.
4377     The connection is invalid if QObject::connect was not able to find
4378     the signal or the slot, or if the arguments do not match.
4379  */
4380
4381 QObject::QSlotObjectBase::~QSlotObjectBase()
4382 {
4383 }
4384
4385 bool QObject::QSlotObjectBase::compare(void** )
4386 {
4387     return false;
4388 }
4389
4390
4391 QT_END_NAMESPACE
4392
4393 #include "moc_qobject.cpp"