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

Last change on this file since 33 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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