source: trunk/src/corelib/kernel/qobject.cpp@ 564

Last change on this file since 564 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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