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