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