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

Last change on this file since 947 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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