~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/kernel/qobject.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qobject.h"
 
30
#include "qobject_p.h"
 
31
 
 
32
#include "qabstracteventdispatcher.h"
 
33
#include "qcoreapplication.h"
 
34
#include "qcoreapplication_p.h"
 
35
#include "qvariant.h"
 
36
#include "qmetaobject.h"
 
37
#include <qregexp.h>
 
38
#include <qthread.h>
 
39
#include <private/qthread_p.h>
 
40
#include <qdebug.h>
 
41
#include <qhash.h>
 
42
#include <qpair.h>
 
43
#include <qvarlengtharray.h>
 
44
#include <qset.h>
 
45
 
 
46
#include <new>
 
47
 
 
48
#include <ctype.h>
 
49
#include <limits.h>
 
50
 
 
51
static const int GUARDED_SIGNAL = INT_MIN;
 
52
static int DIRECT_CONNECTION_ONLY = 0;
 
53
 
 
54
Q_GLOBAL_STATIC(QReadWriteLock, qt_object_read_write_lock)
 
55
QReadWriteLock *QObjectPrivate::readWriteLock() { return qt_object_read_write_lock(); }
 
56
 
 
57
static int *queuedConnectionTypes(const char *signal)
 
58
{
 
59
    int *types = 0;
 
60
    const char *s = signal;
 
61
    while (*s++ != '(') {}
 
62
    int nargs = 0;
 
63
    const char *e = s;
 
64
    while (*e != ')') {
 
65
        ++e;
 
66
        if (*e == ')' || *e == ',')
 
67
            ++nargs;
 
68
    }
 
69
 
 
70
    types = (int *) qMalloc((nargs+1)*sizeof(int));
 
71
    types[nargs] = 0;
 
72
    for (int n = 0; n < nargs; ++n) {
 
73
        e = s;
 
74
        while (*s != ',' && *s != ')')
 
75
            ++s;
 
76
        QByteArray type(e, s-e);
 
77
        ++s;
 
78
 
 
79
        if (type.endsWith('*')) {
 
80
            types[n] = QMetaType::type("void*");
 
81
        } else {
 
82
            types[n] = QMetaType::type(type);
 
83
        }
 
84
        if (!types[n]) {
 
85
            qWarning("QObject::connect: Cannot queue arguments of type '%s'", type.data());
 
86
            qFree(types);
 
87
            return 0;
 
88
        }
 
89
    }
 
90
    return types;
 
91
}
 
92
 
 
93
struct QConnection {
 
94
    QObject *sender;
 
95
    int signal;
 
96
    union {
 
97
        QObject *receiver;
 
98
        QObject **guarded;
 
99
    };
 
100
    int method;
 
101
    int type; // 0 == auto, 1 == direct, 2 == queued
 
102
    int *types;
 
103
};
 
104
 
 
105
class QConnectionList
 
106
{
 
107
public:
 
108
    inline QConnectionList()
 
109
        : invariant(0)
 
110
    { }
 
111
 
 
112
    QReadWriteLock lock;
 
113
 
 
114
    // if zero, we can reuse "free" slots, otherwise we always
 
115
    // append... used in QMetaObject::activate()
 
116
    QAtomic invariant;
 
117
 
 
118
    typedef QMultiHash<const QObject *, int> Hash;
 
119
    Hash sendersHash, receiversHash;
 
120
    QList<int> unusedConnections;
 
121
    typedef QList<QConnection> List;
 
122
    List connections;
 
123
 
 
124
    void remove(QObject *object);
 
125
 
 
126
    void addConnection(QObject *sender, int signal,
 
127
                       QObject *receiver, int method,
 
128
                       int type = 0, int *types = 0);
 
129
    bool removeConnection(QObject *sender, int signal,
 
130
                          QObject *receiver, int method);
 
131
};
 
132
 
 
133
Q_GLOBAL_STATIC(QConnectionList, connectionList)
 
134
 
 
135
/*! \internal
 
136
 
 
137
    Removes \a object from the connection list completely, i.e. all
 
138
    connections containing \a object are removed.
 
139
*/
 
140
void QConnectionList::remove(QObject *object)
 
141
{
 
142
    for (int i = 0; i < 2; ++i) {
 
143
        Hash &hash1 = i == 0 ? sendersHash : receiversHash;
 
144
        Hash &hash2 = i == 0 ? receiversHash : sendersHash;
 
145
 
 
146
        Hash::iterator it = hash1.find(object);
 
147
        const Hash::iterator end = hash1.end();
 
148
        while (it != end && it.key() == object) {
 
149
            const int at = it.value();
 
150
            QConnection &c = connections[at];
 
151
            if (c.sender) {
 
152
                if (c.signal == GUARDED_SIGNAL)
 
153
                    *c.guarded = 0;
 
154
                if (c.types && c.types != &DIRECT_CONNECTION_ONLY) {
 
155
                    qFree(c.types);
 
156
                    c.types = 0;
 
157
                }
 
158
                it = hash1.erase(it);
 
159
 
 
160
                const QObject * const partner = i == 0 ? c.receiver : c.sender;
 
161
                Hash::iterator x = hash2.find(partner);
 
162
                const Hash::iterator xend = hash2.end();
 
163
                while (x != xend && x.key() == partner) {
 
164
                    if (x.value() == at) {
 
165
                        x = hash2.erase(x);
 
166
                        break;
 
167
                    } else {
 
168
                        ++x;
 
169
                    }
 
170
                }
 
171
 
 
172
                memset(&c, 0, sizeof(c));
 
173
                Q_ASSERT(!unusedConnections.contains(at));
 
174
                unusedConnections.prepend(at);
 
175
            } else {
 
176
                ++it;
 
177
            }
 
178
        }
 
179
    }
 
180
}
 
181
 
 
182
/*! \internal
 
183
    Adds the specified connection.
 
184
*/
 
185
void QConnectionList::addConnection(QObject *sender, int signal,
 
186
                                    QObject *receiver, int method,
 
187
                                    int type, int *types)
 
188
{
 
189
    QConnection c = { sender, signal, {receiver}, method, type, types };
 
190
    int at;
 
191
    if (unusedConnections.isEmpty() || invariant != 0) {
 
192
        // append new connection
 
193
        at = connections.size();
 
194
        connections << c;
 
195
    } else {
 
196
        // reuse an unused connection
 
197
        at = unusedConnections.takeFirst();
 
198
        connections[at] = c;
 
199
    }
 
200
    sendersHash.insert(sender, at);
 
201
    receiversHash.insert(receiver, at);
 
202
}
 
203
 
 
204
/*! \internal
 
205
 
 
206
    Removes the specified connection.  See QObject::disconnect() for
 
207
    more information about valid arguments.
 
208
 */
 
209
bool QConnectionList::removeConnection(QObject *sender, int signal,
 
210
                                       QObject *receiver, int method)
 
211
{
 
212
    bool success = false;
 
213
    Hash::iterator it = sendersHash.find(sender);
 
214
    while (it != sendersHash.end() && it.key() == sender) {
 
215
        const int at = it.value();
 
216
        QConnection &c = connections[at];
 
217
        if (c.receiver
 
218
            && ((signal == GUARDED_SIGNAL && c.signal == signal)
 
219
                || (signal < 0 || signal == c.signal))
 
220
            && (receiver == 0
 
221
                || (c.receiver == receiver && (method < 0 || method == c.method)))) {
 
222
            if (c.signal == GUARDED_SIGNAL)
 
223
                *c.guarded = 0;
 
224
            if (c.types) {
 
225
                if (c.types != &DIRECT_CONNECTION_ONLY)
 
226
                    qFree(c.types);
 
227
                c.types = 0;
 
228
            }
 
229
            it = sendersHash.erase(it);
 
230
 
 
231
            Hash::iterator x = receiversHash.find(c.receiver);
 
232
            const Hash::iterator xend = receiversHash.end();
 
233
            while (x != xend && x.key() == c.receiver) {
 
234
                if (x.value() == at) {
 
235
                    x = receiversHash.erase(x);
 
236
                    break;
 
237
                } else {
 
238
                    ++x;
 
239
                }
 
240
            }
 
241
 
 
242
            memset(&c, 0, sizeof(c));
 
243
            unusedConnections << at;
 
244
            success = true;
 
245
        } else {
 
246
            ++it;
 
247
        }
 
248
    }
 
249
    return success;
 
250
}
 
251
 
 
252
 
 
253
Q_GLOBAL_STATIC(QSet<QObject *>, allObjects)
 
254
 
 
255
extern "C" Q_CORE_EXPORT void qt_addObject(QObject *object)
 
256
{
 
257
    QWriteLocker locker(QObjectPrivate::readWriteLock());
 
258
    QSet<QObject *> *set = allObjects();
 
259
    if (set)
 
260
        set->insert(object);
 
261
}
 
262
 
 
263
extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *object)
 
264
{
 
265
    QWriteLocker locker(QObjectPrivate::readWriteLock());
 
266
    QSet<QObject *> *set = allObjects();
 
267
    if (set)
 
268
        set->remove(object);
 
269
}
 
270
 
 
271
bool QObjectPrivate::isValidObject(QObject *object)
 
272
{
 
273
    QSet<QObject *> *set = allObjects();
 
274
    return set ? set->contains(object) : false;
 
275
}
 
276
 
 
277
QObjectPrivate::QObjectPrivate(int version)
 
278
    : thread(0), currentSender(0)
 
279
{
 
280
    if (version != QObjectPrivateVersion)
 
281
        qFatal("Cannot mix incompatible Qt libraries");
 
282
 
 
283
    // QObjectData initialization
 
284
    q_ptr = 0;
 
285
    parent = 0;                                 // no parent yet. It is set by setParent()
 
286
    isWidget = false;                           // assume not a widget object
 
287
    pendTimer = false;                          // no timers yet
 
288
    blockSig = false;                           // not blocking signals
 
289
    wasDeleted = false;                         // double-delete catcher
 
290
    sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent
 
291
    receiveChildEvents = true;
 
292
    postedEvents = 0;
 
293
#ifdef QT3_SUPPORT
 
294
    postedChildInsertedEvents = 0;
 
295
#endif
 
296
}
 
297
 
 
298
QObjectPrivate::~QObjectPrivate()
 
299
{
 
300
#ifndef QT_NO_USERDATA
 
301
    while (!userData.isEmpty())
 
302
        delete userData.takeFirst();
 
303
#endif
 
304
}
 
305
 
 
306
class ConnectionObject : public QObject
 
307
{
 
308
    Q_DECLARE_PRIVATE(QObject)
 
309
public:
 
310
    bool isSender(const QObject *receiver, const char *signal) const;
 
311
    QList<QObject*> receiverList(const char *signal) const;
 
312
    QList<QObject*> senders() const;
 
313
};
 
314
 
 
315
bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
 
316
{
 
317
    Q_Q(const QObject);
 
318
    int signal_index = q->metaObject()->indexOfSignal(signal);
 
319
    if (signal_index < 0)
 
320
        return false;
 
321
    QConnectionList *list = ::connectionList();
 
322
    QReadLocker locker(&list->lock);
 
323
    QConnectionList::Hash::const_iterator it = list->sendersHash.find(q);
 
324
    while (it != list->sendersHash.end() && it.key() == q) {
 
325
        const QConnection &c = list->connections.at(it.value());
 
326
        if (c.signal == signal_index && c.receiver == receiver)
 
327
            return true;
 
328
        ++it;
 
329
    }
 
330
    return false;
 
331
}
 
332
 
 
333
QObjectList QObjectPrivate::receiverList(const char *signal) const
 
334
{
 
335
    Q_Q(const QObject);
 
336
    QObjectList receivers;
 
337
    int signal_index = q->metaObject()->indexOfSignal(signal);
 
338
    if (signal_index < 0)
 
339
        return receivers;
 
340
    QConnectionList *list = ::connectionList();
 
341
    QReadLocker locker(&list->lock);
 
342
    QConnectionList::Hash::const_iterator it = list->sendersHash.find(q);
 
343
    while (it != list->sendersHash.end() && it.key() == q) {
 
344
        const QConnection &c = list->connections.at(it.value());
 
345
        if (c.signal == signal_index)
 
346
            receivers << c.receiver;
 
347
        ++it;
 
348
    }
 
349
    return receivers;
 
350
}
 
351
 
 
352
QObjectList QObjectPrivate::senderList() const
 
353
{
 
354
    Q_Q(const QObject);
 
355
    QObjectList senders;
 
356
    QConnectionList *list = ::connectionList();
 
357
    QReadLocker locker(&list->lock);
 
358
    QConnectionList::Hash::const_iterator it = list->receiversHash.find(q);
 
359
    while (it != list->receiversHash.end() && it.key() == q) {
 
360
        const QConnection &c = list->connections.at(it.value());
 
361
        senders << c.sender;
 
362
    }
 
363
    return senders;
 
364
}
 
365
 
 
366
 
 
367
/*!\internal
 
368
 */
 
369
void QMetaObject::addGuard(QObject **ptr)
 
370
{
 
371
    if (!*ptr)
 
372
        return;
 
373
    QConnectionList *list = ::connectionList();
 
374
    if (!list) {
 
375
        *ptr = 0;
 
376
        return;
 
377
    }
 
378
    QWriteLocker locker(&list->lock);
 
379
    list->addConnection(*ptr, GUARDED_SIGNAL, reinterpret_cast<QObject*>(ptr), 0);
 
380
}
 
381
 
 
382
/*!\internal
 
383
 */
 
384
void QMetaObject::removeGuard(QObject **ptr)
 
385
{
 
386
    if (!*ptr)
 
387
        return;
 
388
    QConnectionList *list = ::connectionList();
 
389
    if (!list)
 
390
        return;
 
391
    QWriteLocker locker(&list->lock);
 
392
    list->removeConnection(*ptr, GUARDED_SIGNAL, reinterpret_cast<QObject*>(ptr), 0);
 
393
}
 
394
 
 
395
/*!\internal
 
396
 */
 
397
void QMetaObject::changeGuard(QObject **ptr, QObject *o)
 
398
{
 
399
    QConnectionList *list = ::connectionList();
 
400
    if (!list) {
 
401
        *ptr = 0;
 
402
        return;
 
403
    }
 
404
    QWriteLocker locker(&list->lock);
 
405
    if (*ptr)
 
406
        list->removeConnection(*ptr, GUARDED_SIGNAL, reinterpret_cast<QObject*>(ptr), 0);
 
407
    *ptr = o;
 
408
    if (*ptr)
 
409
        list->addConnection(*ptr, GUARDED_SIGNAL, reinterpret_cast<QObject*>(ptr), 0);
 
410
}
 
411
 
 
412
/*! \internal
 
413
 */
 
414
QMetaCallEvent::QMetaCallEvent(int id, int nargs, int *types, void **args)
 
415
    :QEvent(MetaCall), id_(id), nargs_(nargs), types_(types), args_(args)
 
416
{ }
 
417
 
 
418
/*! \internal
 
419
 */
 
420
QMetaCallEvent::~QMetaCallEvent()
 
421
{
 
422
    for (int i = 0; i < nargs_; ++i) {
 
423
        if (types_[i] && args_[i])
 
424
            QMetaType::destroy(types_[i], args_[i]);
 
425
    }
 
426
    if (types_) qFree(types_);
 
427
    if (args_) qFree(args_);
 
428
}
 
429
 
 
430
/*!
 
431
    \class QObject
 
432
    \brief The QObject class is the base class of all Qt objects.
 
433
 
 
434
    \ingroup objectmodel
 
435
    \mainclass
 
436
    \reentrant
 
437
 
 
438
    QObject is the heart of the \l{Qt object model}. The central
 
439
    feature in this model is a very powerful mechanism for seamless
 
440
    object communication called \l{signals and slots}. You can
 
441
    connect a signal to a slot with connect() and destroy the
 
442
    connection with disconnect(). To avoid never ending notification
 
443
    loops you can temporarily block signals with blockSignals(). The
 
444
    protected functions connectNotify() and disconnectNotify() make
 
445
    it possible to track connections.
 
446
 
 
447
    QObjects organize themselves in object trees. When you create a
 
448
    QObject with another object as parent, the object will
 
449
    automatically add itself to the parent's children() list. The
 
450
    parent takes ownership of the object i.e. it will automatically
 
451
    delete its children in its destructor. You can look for an object
 
452
    by name and optionally type using findChild() or findChildren().
 
453
 
 
454
    Every object has an objectName() and its class name can be found
 
455
    via the corresponding metaObject() (see QMetaObject::className()).
 
456
    You can determine whether the object's class inherits another
 
457
    class in the QObject inheritance hierarchy by using the
 
458
    inherits() function.
 
459
 
 
460
    When an object is deleted, it emits a destroyed() signal. You can
 
461
    catch this signal to avoid dangling references to QObjects. The
 
462
    QPointer class provides an elegant way to use this feature.
 
463
 
 
464
    QObjects can receive events through event() and filter the events
 
465
    of other objects. See installEventFilter() and eventFilter() for
 
466
    details. A convenience handler, childEvent(), can be
 
467
    reimplemented to catch child events. Events are delivered in the
 
468
    thread in which the object was created; see \l{Thread Support in
 
469
    Qt} and thread() for details.
 
470
 
 
471
    Last but not least, QObject provides the basic timer support in
 
472
    Qt; see QTimer for high-level support for timers.
 
473
 
 
474
    Notice that the Q_OBJECT macro is mandatory for any object that
 
475
    implements signals, slots or properties. You also need to run the
 
476
    \l{moc}{Meta Object Compiler} on the source file. We strongly
 
477
    recommend the use of this macro in all subclasses of QObject
 
478
    regardless of whether or not they actually use signals, slots and
 
479
    properties, since failure to do so may lead certain functions to
 
480
    exhibit strange behavior.
 
481
 
 
482
    All Qt widgets inherit QObject. The convenience function
 
483
    isWidgetType() returns whether an object is actually a widget. It
 
484
    is much faster than
 
485
    \l{qobject_cast()}{qobject_cast}<QWidget>(\e{obj}) or
 
486
    \e{obj}->\l{inherits()}{inherits}("QWidget").
 
487
 
 
488
    Some QObject functions, e.g. children(), return a \c QObjectList.
 
489
    \c QObjectList is a typedef for QList<QObject *>.
 
490
 
 
491
    \sa QMetaObject, QPointer, QObjectCleanupHandler,
 
492
        {Object Trees and Object Ownership}
 
493
*/
 
494
 
 
495
/*!
 
496
    \relates QObject
 
497
 
 
498
    Returns a pointer to the object named \a name that inherits \a
 
499
    type and with a given \a parent.
 
500
 
 
501
    Returns 0 if there is no such child.
 
502
 
 
503
    \code
 
504
        QLineEdit *lineEdit = static_cast<QLineEdit *>(
 
505
                qt_find_obj_child(myWidget, "QLineEdit", "my line edit"));
 
506
        if (lineEdit)
 
507
            lineEdit->setText("Default");
 
508
    \endcode
 
509
*/
 
510
 
 
511
void *qt_find_obj_child(QObject *parent, const char *type, const QString &name)
 
512
{
 
513
    QObjectList list = parent->children();
 
514
    if (list.size() == 0) return 0;
 
515
    for (int i = 0; i < list.size(); ++i) {
 
516
        QObject *obj = list.at(i);
 
517
        if (name == obj->objectName() && obj->inherits(type))
 
518
            return obj;
 
519
    }
 
520
    return 0;
 
521
}
 
522
 
 
523
 
 
524
/*****************************************************************************
 
525
  QObject member functions
 
526
 *****************************************************************************/
 
527
 
 
528
/*!
 
529
    Constructs an object with parent object \a parent.
 
530
 
 
531
    The parent of an object may be viewed as the object's owner. For
 
532
    instance, a \l{QDialog}{dialog box} is the parent of the \gui OK
 
533
    and \gui Cancel buttons it contains.
 
534
 
 
535
    The destructor of a parent object destroys all child objects.
 
536
 
 
537
    Setting \a parent to 0 constructs an object with no parent. If the
 
538
    object is a widget, it will become a top-level window.
 
539
 
 
540
    \sa parent(), findChild(), findChildren()
 
541
*/
 
542
 
 
543
QObject::QObject(QObject *parent)
 
544
    : d_ptr(new QObjectPrivate)
 
545
{
 
546
    Q_D(QObject);
 
547
    ::qt_addObject(d_ptr->q_ptr = this);
 
548
    if (parent) {
 
549
        d->thread = parent->d_func()->thread;
 
550
    } else {
 
551
        QThread *currentThread = QThread::currentThread();
 
552
        d->thread = currentThread ? QThreadData::get(currentThread)->id : -1;
 
553
    }
 
554
    setParent(parent);
 
555
}
 
556
 
 
557
#ifdef QT3_SUPPORT
 
558
/*!
 
559
    \overload
 
560
    \obsolete
 
561
 
 
562
    Creates a new QObject with the given \a parent and object \a name.
 
563
 */
 
564
QObject::QObject(QObject *parent, const char *name)
 
565
    : d_ptr(new QObjectPrivate)
 
566
{
 
567
    Q_D(QObject);
 
568
    ::qt_addObject(d_ptr->q_ptr = this);
 
569
    if (parent) {
 
570
        d->thread = parent->d_func()->thread;
 
571
    } else {
 
572
        QThread *currentThread = QThread::currentThread();
 
573
        d->thread = currentThread ? QThreadData::get(currentThread)->id : -1;
 
574
    }
 
575
    setParent(parent);
 
576
    setObjectName(QString::fromAscii(name));
 
577
}
 
578
#endif
 
579
 
 
580
/*! \internal
 
581
 */
 
582
QObject::QObject(QObjectPrivate &dd, QObject *parent)
 
583
    : d_ptr(&dd)
 
584
{
 
585
    Q_D(QObject);
 
586
    ::qt_addObject(d_ptr->q_ptr = this);
 
587
    if (parent) {
 
588
        d->thread = parent->d_func()->thread;
 
589
    } else {
 
590
        QThread *currentThread = QThread::currentThread();
 
591
        d->thread = currentThread ? QThreadData::get(currentThread)->id : -1;
 
592
    }
 
593
    if (d->isWidget) {
 
594
        if (parent) {
 
595
            d->parent = parent;
 
596
            d->parent->d_func()->children.append(this);
 
597
        }
 
598
        // no events sent here, this is done at the end of the QWidget constructor
 
599
    } else {
 
600
        setParent(parent);
 
601
    }
 
602
}
 
603
 
 
604
/*!
 
605
    Destroys the object, deleting all its child objects.
 
606
 
 
607
    All signals to and from the object are automatically disconnected.
 
608
 
 
609
    \warning All child objects are deleted. If any of these objects
 
610
    are on the stack or global, sooner or later your program will
 
611
    crash. We do not recommend holding pointers to child objects from
 
612
    outside the parent. If you still do, the destroyed() signal gives
 
613
    you an opportunity to detect when an object is destroyed.
 
614
 
 
615
    \warning Deleting a QObject while pending events are waiting to
 
616
    be delivered can cause a crash. You must not delete the QObject
 
617
    directly from a thread that is not the GUI thread.  Use the
 
618
    deleteLater() method instead, which will cause the event loop to
 
619
    delete the object after all pending events have been delivered to
 
620
    the object.
 
621
 
 
622
    \sa deleteLater()
 
623
*/
 
624
 
 
625
QObject::~QObject()
 
626
{
 
627
    Q_D(QObject);
 
628
    if (d->wasDeleted) {
 
629
#if defined(QT_DEBUG)
 
630
        qWarning("Double QObject deletion detected");
 
631
#endif
 
632
        return;
 
633
    }
 
634
    d->wasDeleted = true;
 
635
 
 
636
    d->blockSig = 0; // unblock signals so we always emit destroyed()
 
637
    emit destroyed(this);
 
638
 
 
639
    QConnectionList *list = ::connectionList();
 
640
    if (list) {
 
641
        QWriteLocker locker(&list->lock);
 
642
        list->remove(this);
 
643
    }
 
644
 
 
645
    if (d->pendTimer) {
 
646
        // have pending timers
 
647
        QThread *thr = thread();
 
648
        if (thr || d->thread == 0) {
 
649
            // don't unregister timers in the wrong thread
 
650
            QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thr);
 
651
            if (eventDispatcher)
 
652
                eventDispatcher->unregisterTimers(this);
 
653
        }
 
654
    }
 
655
 
 
656
    d->eventFilters.clear();
 
657
 
 
658
    while (!d->children.isEmpty())                        // delete children objects
 
659
        delete d->children.takeFirst();
 
660
 
 
661
    ::qt_removeObject(this);
 
662
    QCoreApplication::removePostedEvents(this);
 
663
 
 
664
    if (d->parent)                                // remove it from parent object
 
665
        d->setParent_helper(0);
 
666
 
 
667
    delete d;
 
668
    d_ptr = 0;
 
669
}
 
670
 
 
671
 
 
672
/*!
 
673
    \fn QMetaObject *QObject::metaObject() const
 
674
 
 
675
    Returns a pointer to the meta object of this object.
 
676
 
 
677
    A meta object contains information about a class that inherits
 
678
    QObject, e.g. class name, superclass name, properties, signals and
 
679
    slots. Every class that contains the Q_OBJECT macro will also have
 
680
    a meta object.
 
681
 
 
682
    The meta object information is required by the signal/slot
 
683
    connection mechanism and the property system. The inherits()
 
684
    function also makes use of the meta object.
 
685
*/
 
686
 
 
687
/*! \fn T *qobject_cast<T *>(QObject *object)
 
688
 
 
689
    \relates QObject
 
690
 
 
691
    Returns the given \a object cast to type T if the object is of type
 
692
    T (or of a subclass); otherwise returns 0.
 
693
 
 
694
    A class is considered to inherit itself.
 
695
 
 
696
    Example:
 
697
 
 
698
    \code
 
699
        QObject *obj = new QTimer;          // QTimer inherits QObject
 
700
 
 
701
        QTimer *timer = qobject_cast<QTimer *>(obj);
 
702
        // timer == (QObject *)obj
 
703
 
 
704
        QAbstractButton *button = qobject_cast<QAbstractButton *)(obj);
 
705
        // button == 0
 
706
    \endcode
 
707
 
 
708
    The qobject_cast() function behaves similarly to the standard C++
 
709
    \c dynamic_cast(), with the advantages that it doesn't require
 
710
    RTTI support and it works across dynamic library boundaries.
 
711
 
 
712
    qobject_cast() can also be used in conjunction with interfaces;
 
713
    see the \l{tools/plugandpaint}{Plug & Paint} example for details.
 
714
 
 
715
    \sa QObject::inherits()
 
716
*/
 
717
 
 
718
/*!
 
719
    \fn bool QObject::inherits(const char *className) const
 
720
 
 
721
    Returns true if this object is an instance of a class that
 
722
    inherits \a className or a QObject subclass that inherits \a
 
723
    className; otherwise returns false.
 
724
 
 
725
    A class is considered to inherit itself.
 
726
 
 
727
    Example:
 
728
 
 
729
    \code
 
730
        QTimer *timer = new QTimer;         // QTimer inherits QObject
 
731
        timer->inherits("QTimer");          // returns true
 
732
        timer->inherits("QObject");         // returns true
 
733
        timer->inherits("QAbstractButton"); // returns false
 
734
 
 
735
        // QLayout inherits QObject and QLayoutItem
 
736
        QLayout *layout = new QLayout;
 
737
        layout->inherits("QObject");        // returns true
 
738
        layout->inherits("QLayoutItem");    // returns false
 
739
    \endcode
 
740
 
 
741
    (\l QLayoutItem is not a QObject.)
 
742
 
 
743
    Consider using qobject_cast<Type *>(object) instead. The method
 
744
    is both faster and safer.
 
745
 
 
746
    \sa metaObject(), qobject_cast()
 
747
*/
 
748
 
 
749
/*!
 
750
    \property QObject::objectName
 
751
 
 
752
    \brief the name of this object
 
753
 
 
754
    You can find an object by name (and type) using findChild(). You can
 
755
    find a set of objects with findChildren().
 
756
 
 
757
    \code
 
758
        qDebug("MyClass::setPrecision(): (%s) invalid precision %f",
 
759
               qPrintable(objectName()), newPrecision);
 
760
    \endcode
 
761
 
 
762
    \sa metaObject(), QMetaObject::className()
 
763
*/
 
764
 
 
765
QString QObject::objectName() const
 
766
{
 
767
    Q_D(const QObject);
 
768
    return d->objectName;
 
769
}
 
770
 
 
771
/*
 
772
    Sets the object's name to \a name.
 
773
*/
 
774
void QObject::setObjectName(const QString &name)
 
775
{
 
776
    Q_D(QObject);
 
777
    d->objectName = name;
 
778
}
 
779
 
 
780
 
 
781
#ifdef QT3_SUPPORT
 
782
/*! \internal
 
783
    QObject::child is compat but needs to call itself recursively,
 
784
    that's why we need this helper.
 
785
*/
 
786
static QObject *qChildHelper(const char *objName, const char *inheritsClass,
 
787
                             bool recursiveSearch, const QObjectList &children)
 
788
{
 
789
    if (children.isEmpty())
 
790
        return 0;
 
791
 
 
792
    bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
 
793
    const QLatin1String oName(objName);
 
794
    for (int i = 0; i < children.size(); ++i) {
 
795
        QObject *obj = children.at(i);
 
796
        if (onlyWidgets) {
 
797
            if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
 
798
                return obj;
 
799
        } else if ((!inheritsClass || obj->inherits(inheritsClass))
 
800
                   && (!objName || obj->objectName() == oName))
 
801
            return obj;
 
802
        if (recursiveSearch && (obj = qChildHelper(objName, inheritsClass,
 
803
                                                   recursiveSearch, obj->children())))
 
804
            return obj;
 
805
    }
 
806
    return 0;
 
807
}
 
808
 
 
809
 
 
810
/*!
 
811
    Searches the children and optionally grandchildren of this object,
 
812
    and returns a child that is called \a objName that inherits \a
 
813
    inheritsClass. If \a inheritsClass is 0 (the default), any class
 
814
    matches.
 
815
 
 
816
    If \a recursiveSearch is true (the default), child() performs a
 
817
    depth-first search of the object's children.
 
818
 
 
819
    If there is no such object, this function returns 0. If there are
 
820
    more than one, the first one found is retured; if you need all of
 
821
    them, use queryList().
 
822
*/
 
823
QObject* QObject::child(const char *objName, const char *inheritsClass,
 
824
                         bool recursiveSearch) const
 
825
{
 
826
    Q_D(const QObject);
 
827
    return qChildHelper(objName, inheritsClass, recursiveSearch, d->children);
 
828
}
 
829
#endif
 
830
 
 
831
/*!
 
832
    \fn bool QObject::isWidgetType() const
 
833
 
 
834
    Returns true if the object is a widget; otherwise returns false.
 
835
 
 
836
    Calling this function is equivalent to calling
 
837
    inherits("QWidget"), except that it is much faster.
 
838
*/
 
839
 
 
840
 
 
841
/*!
 
842
    This virtual function receives events to an object and should
 
843
    return true if the event \a e was recognized and processed.
 
844
 
 
845
    The event() function can be reimplemented to customize the
 
846
    behavior of an object.
 
847
 
 
848
    \sa installEventFilter(), timerEvent(), QApplication::sendEvent(),
 
849
    QApplication::postEvent(), QWidget::event()
 
850
*/
 
851
 
 
852
bool QObject::event(QEvent *e)
 
853
{
 
854
    switch (e->type()) {
 
855
    case QEvent::Timer:
 
856
        timerEvent((QTimerEvent*)e);
 
857
        break;
 
858
 
 
859
    case QEvent::ChildAdded:
 
860
    case QEvent::ChildPolished:
 
861
#ifdef QT3_SUPPORT
 
862
    case QEvent::ChildInserted:
 
863
#endif
 
864
    case QEvent::ChildRemoved:
 
865
        childEvent((QChildEvent*)e);
 
866
        break;
 
867
 
 
868
    case QEvent::DeferredDelete:
 
869
        delete this;
 
870
        break;
 
871
 
 
872
    case QEvent::MetaCall: {
 
873
        QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
 
874
        // #### should set current sender to 0 and reset after metacall.
 
875
        // Problem is a delete this in the slot making this difficult.
 
876
        qt_metacall(QMetaObject::InvokeMetaMethod, mce->id(), mce->args());
 
877
        break;
 
878
    }
 
879
 
 
880
    case QEvent::ThreadChange: {
 
881
        QThread *objectThread = thread();
 
882
        if (objectThread) {
 
883
            QThreadData *threadData = QThreadData::get(objectThread);
 
884
            QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
 
885
            QList<QPair<int, int> > timers = eventDispatcher->registeredTimers(this);
 
886
            if (!timers.isEmpty()) {
 
887
                eventDispatcher->unregisterTimers(this);
 
888
                QMetaObject::invokeMethod(this, "reregisterTimers", Qt::QueuedConnection,
 
889
                                          Q_ARG(void*, (new QList<QPair<int, int> >(timers))));
 
890
            }
 
891
        }
 
892
        break;
 
893
    }
 
894
 
 
895
    default:
 
896
        if (e->type() >= QEvent::User) {
 
897
            customEvent(e);
 
898
            break;
 
899
        }
 
900
        return false;
 
901
    }
 
902
    return true;
 
903
}
 
904
 
 
905
/*!
 
906
    \fn void QObject::timerEvent(QTimerEvent *event)
 
907
 
 
908
    This event handler can be reimplemented in a subclass to receive
 
909
    timer events for the object.
 
910
 
 
911
    QTimer provides a higher-level interface to the timer
 
912
    functionality, and also more general information about timers. The
 
913
    timer event is passed in the \a event parameter.
 
914
 
 
915
    \sa startTimer(), killTimer(), event()
 
916
*/
 
917
 
 
918
void QObject::timerEvent(QTimerEvent *)
 
919
{
 
920
}
 
921
 
 
922
 
 
923
/*!
 
924
    This event handler can be reimplemented in a subclass to receive
 
925
    child events. The event is passed in the \a event parameter.
 
926
 
 
927
    QEvent::ChildAdded and QEvent::ChildRemoved events are sent to
 
928
    objects when children are added or removed. In both cases you can
 
929
    only rely on the child being a QObject, or if isWidgetType()
 
930
    returns true, a QWidget. (This is because, in the
 
931
    \l{QEvent::ChildAdded}{ChildAdded} case, the child is not yet
 
932
    fully constructed, and in the \l{QEvent::ChildRemoved}{ChildRemoved}
 
933
    case it might have been destructed already).
 
934
 
 
935
    QEvent::ChildPolished events are sent to widgets when children
 
936
    are polished, or when polished children are added. If you receive
 
937
    a child polished event, the child's construction is usually
 
938
    completed.
 
939
 
 
940
    For every child widget, you receive one
 
941
    \l{QEvent::ChildAdded}{ChildAdded} event, zero or more
 
942
    \l{QEvent::ChildPolished}{ChildPolished} events, and one
 
943
    \l{QEvent::ChildRemoved}{ChildRemoved} event.
 
944
 
 
945
    The \l{QEvent::ChildPolished}{ChildPolished} event is omitted if
 
946
    a child is removed immediately after it is added. If a child is
 
947
    polished several times during construction and destruction, you
 
948
    may receive several child polished events for the same child,
 
949
    each time with a different virtual table.
 
950
 
 
951
    \sa event()
 
952
*/
 
953
 
 
954
void QObject::childEvent(QChildEvent * /* event */)
 
955
{
 
956
}
 
957
 
 
958
 
 
959
/*!
 
960
    This event handler can be reimplemented in a subclass to receive
 
961
    custom events. Custom events are user-defined events with a type
 
962
    value at least as large as the QEvent::User item of the
 
963
    QEvent::Type enum, and is typically a QEvent subclass. The event
 
964
    is passed in the \a event parameter.
 
965
 
 
966
    \sa event(), QEvent
 
967
*/
 
968
void QObject::customEvent(QEvent * /* event */)
 
969
{
 
970
}
 
971
 
 
972
 
 
973
 
 
974
/*!
 
975
    Filters events if this object has been installed as an event
 
976
    filter for the \a watched object.
 
977
 
 
978
    In your reimplementation of this function, if you want to filter
 
979
    the \a event out, i.e. stop it being handled further, return
 
980
    true; otherwise return false.
 
981
 
 
982
    Example:
 
983
    \code
 
984
        class MainWindow : public QMainWindow
 
985
        {
 
986
        public:
 
987
            MainWindow();
 
988
 
 
989
        protected:
 
990
            bool eventFilter(QObject *obj, QEvent *ev);
 
991
 
 
992
        private:
 
993
            QTextEdit *textEdit;
 
994
        };
 
995
 
 
996
        MainWindow::MainWindow()
 
997
        {
 
998
            textEdit = new QTextEdit;
 
999
            setCentralWidget(textEdit);
 
1000
 
 
1001
            textEdit->installEventFilter(this);
 
1002
        }
 
1003
 
 
1004
        bool MainWindow::eventFilter(QObject *obj, QEvent *event)
 
1005
        {
 
1006
            if (obj == textEdit) {
 
1007
                if (event->type() == QEvent::KeyPress) {
 
1008
                    qDebug("Ate key press");
 
1009
                    return true;
 
1010
                } else {
 
1011
                    return false;
 
1012
                }
 
1013
            } else {
 
1014
                // pass the event on to the parent class
 
1015
                return QMainWindow::eventFilter(obj, event);
 
1016
            }
 
1017
        }
 
1018
    \endcode
 
1019
 
 
1020
    Notice in the example above that unhandled events are passed to
 
1021
    the base class's eventFilter() function, since the base class
 
1022
    might have reimplemented eventFilter() for its own internal
 
1023
    purposes.
 
1024
 
 
1025
    \warning If you delete the receiver object in this function, be
 
1026
    sure to return true. Otherwise, Qt will forward the event to the
 
1027
    deleted object and the program might crash.
 
1028
 
 
1029
    \sa installEventFilter()
 
1030
*/
 
1031
 
 
1032
bool QObject::eventFilter(QObject * /* watched */, QEvent * /* event */)
 
1033
{
 
1034
    return false;
 
1035
}
 
1036
 
 
1037
/*!
 
1038
    \fn bool QObject::signalsBlocked() const
 
1039
 
 
1040
    Returns true if signals are blocked; otherwise returns false.
 
1041
 
 
1042
    Signals are not blocked by default.
 
1043
 
 
1044
    \sa blockSignals()
 
1045
*/
 
1046
 
 
1047
/*!
 
1048
    Blocks signals if \a block is true, or unblocks signals if \a
 
1049
    block is false.
 
1050
 
 
1051
    Emitted signals disappear into hyperspace if signals are blocked.
 
1052
    Note that the destroyed() signals will be emitted even if the signals
 
1053
    for this object have been blocked.
 
1054
 
 
1055
    \sa signalsBlocked()
 
1056
*/
 
1057
 
 
1058
bool QObject::blockSignals(bool block)
 
1059
{
 
1060
    Q_D(QObject);
 
1061
    bool previous = d->blockSig;
 
1062
    d->blockSig = block;
 
1063
    return previous;
 
1064
}
 
1065
 
 
1066
/*!
 
1067
    Returns the thread in which the object lives.
 
1068
 
 
1069
    \sa moveToThread()
 
1070
*/
 
1071
QThread *QObject::thread() const
 
1072
{ return QThreadPrivate::threadForId(d_func()->thread); }
 
1073
 
 
1074
/*!
 
1075
    Changes this object's thread affinity.  Event processing for this
 
1076
    object will continue in the \a targetThread.  If \a targetThread
 
1077
    is zero, only \l{QCoreApplication::postEvent()}{posted events} are
 
1078
    processed by the main thread; all other event processing for this
 
1079
    object stops.
 
1080
 
 
1081
    \warning This function is \e not thread-safe; the current thread
 
1082
    must be same as the current thread affinity. In other words, this
 
1083
    function can only "push" an object from the current thread to
 
1084
    another thread, it cannot "pull" an object from any arbitrary
 
1085
    thread to the current thread.
 
1086
 
 
1087
    \sa thread()
 
1088
 */
 
1089
void QObject::moveToThread(QThread *targetThread)
 
1090
{
 
1091
    Q_D(QObject);
 
1092
    Q_ASSERT_X(d->parent == 0, "QObject::moveToThread",
 
1093
               "Cannot move objects with a parent");
 
1094
    if (d->parent != 0)
 
1095
        return;
 
1096
    Q_ASSERT_X(!d->isWidget, "QObject::moveToThread",
 
1097
               "Widgets cannot be moved to a new thread");
 
1098
    if (d->isWidget)
 
1099
        return;
 
1100
    QThread *objectThread = thread();
 
1101
    QThread *currentThread = QThread::currentThread();
 
1102
    Q_ASSERT_X(d->thread == -1 || objectThread == currentThread, "QObject::moveToThread",
 
1103
               "Current thread is not the object's thread");
 
1104
    if (d->thread != -1 && objectThread != currentThread)
 
1105
        return;
 
1106
    if (objectThread == targetThread)
 
1107
        return;
 
1108
 
 
1109
    d->moveToThread_helper(targetThread);
 
1110
 
 
1111
    QWriteLocker locker(QObjectPrivate::readWriteLock());
 
1112
    QThreadData *currentData = QThreadData::get(currentThread);
 
1113
    QThreadData *targetData =
 
1114
        QThreadData::get(targetThread ? targetThread : QCoreApplicationPrivate::mainThread());
 
1115
    if (currentData != targetData) {
 
1116
        targetData->postEventList.mutex.lock();
 
1117
        while (!currentData->postEventList.mutex.tryLock()) {
 
1118
            targetData->postEventList.mutex.unlock();
 
1119
            targetData->postEventList.mutex.lock();
 
1120
        }
 
1121
    }
 
1122
    d_func()->setThreadId_helper(currentData, targetData,
 
1123
                                 targetThread ? QThreadData::get(targetThread)->id : -1);
 
1124
    if (currentData != targetData) {
 
1125
        targetData->postEventList.mutex.unlock();
 
1126
        currentData->postEventList.mutex.unlock();
 
1127
    }
 
1128
}
 
1129
 
 
1130
void QObjectPrivate::moveToThread_helper(QThread *targetThread)
 
1131
{
 
1132
    Q_Q(QObject);
 
1133
    QEvent e(QEvent::ThreadChange);
 
1134
    QCoreApplication::sendEvent(q, &e);
 
1135
    for (int i = 0; i < children.size(); ++i) {
 
1136
        QObject *child = children.at(i);
 
1137
        child->d_func()->moveToThread_helper(targetThread);
 
1138
    }
 
1139
}
 
1140
 
 
1141
void QObjectPrivate::setThreadId_helper(QThreadData *currentData, QThreadData *targetData,
 
1142
                                      int newThreadId)
 
1143
{
 
1144
    Q_Q(QObject);
 
1145
 
 
1146
    if (currentData != targetData) {
 
1147
        // move posted events
 
1148
        int eventsMoved = 0;
 
1149
        for (int i = 0; i < currentData->postEventList.size(); ++i) {
 
1150
            const QPostEvent &pe = currentData->postEventList.at(i);
 
1151
            if (!pe.event)
 
1152
                continue;
 
1153
            if (pe.receiver == q) {
 
1154
                // move this post event to the targetList
 
1155
                targetData->postEventList.append(pe);
 
1156
                const_cast<QPostEvent &>(pe).event = 0;
 
1157
                ++eventsMoved;
 
1158
            }
 
1159
        }
 
1160
        if (eventsMoved > 0 && targetData->eventDispatcher)
 
1161
            targetData->eventDispatcher->wakeUp();
 
1162
    }
 
1163
 
 
1164
    // set new thread id
 
1165
    thread = newThreadId;
 
1166
    for (int i = 0; i < children.size(); ++i) {
 
1167
        QObject *child = children.at(i);
 
1168
        child->d_func()->setThreadId_helper(currentData, targetData, newThreadId);
 
1169
    }
 
1170
}
 
1171
 
 
1172
void QObjectPrivate::reregisterTimers(void *pointer)
 
1173
{
 
1174
    Q_Q(QObject);
 
1175
    QThread *objectThread = q->thread();
 
1176
    QList<QPair<int, int> > *timerList =
 
1177
        reinterpret_cast<QList<QPair<int, int> > *>(pointer);
 
1178
    if (objectThread) {
 
1179
        QThreadData *threadData = QThreadData::get(objectThread);
 
1180
        QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
 
1181
        for (int i = 0; i < timerList->size(); ++i) {
 
1182
            const QPair<int, int> &pair = timerList->at(i);
 
1183
            eventDispatcher->registerTimer(pair.first, pair.second, q);
 
1184
        }
 
1185
    }
 
1186
    delete timerList;
 
1187
}
 
1188
 
 
1189
 
 
1190
//
 
1191
// The timer flag hasTimer is set when startTimer is called.
 
1192
// It is not reset when killing the timer because more than
 
1193
// one timer might be active.
 
1194
//
 
1195
 
 
1196
/*!
 
1197
    Starts a timer and returns a timer identifier, or returns zero if
 
1198
    it could not start a timer.
 
1199
 
 
1200
    A timer event will occur every \a interval milliseconds until
 
1201
    killTimer() is called. If \a interval is 0, then the timer event
 
1202
    occurs once every time there are no more window system events to
 
1203
    process.
 
1204
 
 
1205
    The virtual timerEvent() function is called with the QTimerEvent
 
1206
    event parameter class when a timer event occurs. Reimplement this
 
1207
    function to get timer events.
 
1208
 
 
1209
    If multiple timers are running, the QTimerEvent::timerId() can be
 
1210
    used to find out which timer was activated.
 
1211
 
 
1212
    Example:
 
1213
 
 
1214
    \code
 
1215
        class MyObject : public QObject
 
1216
        {
 
1217
            Q_OBJECT
 
1218
 
 
1219
        public:
 
1220
            MyObject(QObject *parent = 0);
 
1221
 
 
1222
        protected:
 
1223
            void timerEvent(QTimerEvent *event);
 
1224
        };
 
1225
 
 
1226
        MyObject::MyObject(QObject *parent)
 
1227
            : QObject(parent)
 
1228
        {
 
1229
            startTimer(50);     // 50-millisecond timer
 
1230
            startTimer(1000);   // 1-second timer
 
1231
            startTimer(60000);  // 1-minute timer
 
1232
        }
 
1233
 
 
1234
        void MyObject::timerEvent(QTimerEvent *event)
 
1235
        {
 
1236
            qDebug() << "Timer ID:" << event->timerId();
 
1237
        }
 
1238
    \endcode
 
1239
 
 
1240
    Note that QTimer's accuracy depends on the underlying operating
 
1241
    system and hardware. Most platforms support an accuracy of 20
 
1242
    milliseconds; some provide more. If Qt is unable to deliver the
 
1243
    requested number of timer events, it will silently discard some.
 
1244
 
 
1245
    The QTimer class provides a high-level programming interface with
 
1246
    single-shot timers and timer signals instead of events. There is
 
1247
    also a QBasicTimer class that is more lightweight than QTimer and
 
1248
    less clumsy than using timer IDs directly.
 
1249
 
 
1250
    \sa timerEvent(), killTimer(), QTimer::singleShot()
 
1251
*/
 
1252
 
 
1253
int QObject::startTimer(int interval)
 
1254
{
 
1255
    Q_D(QObject);
 
1256
    QThread *thr = thread();
 
1257
    if (!thr && d->thread != 0) {
 
1258
        qWarning("QTimer can only be used with a valid thread");
 
1259
        return 0;
 
1260
    }
 
1261
 
 
1262
    d->pendTimer = true;                                // set timer flag
 
1263
    QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thr);
 
1264
    if (!eventDispatcher) {
 
1265
        qWarning("QTimer can only be used with threads started with QThread");
 
1266
        return 0;
 
1267
    }
 
1268
    return eventDispatcher->registerTimer(interval, this);
 
1269
}
 
1270
 
 
1271
/*!
 
1272
    Kills the timer with timer identifier, \a id.
 
1273
 
 
1274
    The timer identifier is returned by startTimer() when a timer
 
1275
    event is started.
 
1276
 
 
1277
    \sa timerEvent(), startTimer()
 
1278
*/
 
1279
 
 
1280
void QObject::killTimer(int id)
 
1281
{
 
1282
    Q_D(QObject);
 
1283
    QThread *thr = thread();
 
1284
    if (!thr && d->thread != 0) {
 
1285
        qWarning("QTimer can only be used with a valid thread");
 
1286
        return;
 
1287
    }
 
1288
 
 
1289
    QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thread());
 
1290
    if (eventDispatcher)
 
1291
        eventDispatcher->unregisterTimer(id);
 
1292
}
 
1293
 
 
1294
 
 
1295
/*!
 
1296
    \fn QObject *QObject::parent() const
 
1297
 
 
1298
    Returns a pointer to the parent object.
 
1299
 
 
1300
    \sa children()
 
1301
*/
 
1302
 
 
1303
/*!
 
1304
    \fn const QObjectList &QObject::children() const
 
1305
 
 
1306
    Returns a list of child objects.
 
1307
    The QObjectList class is defined in the \c{<QObject>} header
 
1308
    file as the following:
 
1309
 
 
1310
    \quotefromfile src/corelib/kernel/qobject.h
 
1311
    \skipto /typedef .*QObjectList/
 
1312
    \printuntil QObjectList
 
1313
 
 
1314
    The first child added is the \l{QList::first()}{first} object in
 
1315
    the list and the last child added is the \l{QList::last()}{last}
 
1316
    object in the list, i.e. new children are appended at the end.
 
1317
 
 
1318
    Note that the list order changes when QWidget children are
 
1319
    \l{QWidget::raise()}{raised} or \l{QWidget::lower()}{lowered}. A
 
1320
    widget that is raised becomes the last object in the list, and a
 
1321
    widget that is lowered becomes the first object in the list.
 
1322
 
 
1323
    \sa findChild(), findChildren(), parent(), setParent()
 
1324
*/
 
1325
 
 
1326
#ifdef QT3_SUPPORT
 
1327
static void objSearch(QObjectList &result,
 
1328
                       const QObjectList &list,
 
1329
                       const char  *inheritsClass,
 
1330
                       bool onlyWidgets,
 
1331
                       const char  *objName,
 
1332
                       QRegExp           *rx,
 
1333
                       bool            recurse)
 
1334
{
 
1335
    for (int i = 0; i < list.size(); ++i) {
 
1336
        QObject *obj = list.at(i);
 
1337
        bool ok = true;
 
1338
        if (onlyWidgets)
 
1339
            ok = obj->isWidgetType();
 
1340
        else if (inheritsClass && !obj->inherits(inheritsClass))
 
1341
            ok = false;
 
1342
        if (ok) {
 
1343
            if (objName)
 
1344
                ok = (obj->objectName() == QLatin1String(objName));
 
1345
#ifndef QT_NO_REGEXP
 
1346
            else if (rx)
 
1347
                ok = (rx->indexIn(obj->objectName()) != -1);
 
1348
#endif
 
1349
        }
 
1350
        if (ok)                                // match!
 
1351
            result.append(obj);
 
1352
        if (recurse) {
 
1353
            QObjectList clist = obj->children();
 
1354
            if (!clist.isEmpty())
 
1355
                objSearch(result, clist, inheritsClass,
 
1356
                           onlyWidgets, objName, rx, recurse);
 
1357
        }
 
1358
    }
 
1359
}
 
1360
 
 
1361
/*!
 
1362
    \internal
 
1363
 
 
1364
    Searches the children and optionally grandchildren of this object,
 
1365
    and returns a list of those objects that are named or that match
 
1366
    \a objName and inherit \a inheritsClass. If \a inheritsClass is 0
 
1367
    (the default), all classes match. If \a objName is 0 (the
 
1368
    default), all object names match.
 
1369
 
 
1370
    If \a regexpMatch is true (the default), \a objName is a regular
 
1371
    expression that the objects's names must match. The syntax is that
 
1372
    of a QRegExp. If \a regexpMatch is false, \a objName is a string
 
1373
    and object names must match it exactly.
 
1374
 
 
1375
    Note that \a inheritsClass uses single inheritance from QObject,
 
1376
    the way inherits() does. According to inherits(), QWidget
 
1377
    inherits QObject but not QPaintDevice. This does not quite match
 
1378
    reality, but is the best that can be done on the wide variety of
 
1379
    compilers Qt supports.
 
1380
 
 
1381
    Finally, if \a recursiveSearch is true (the default), queryList()
 
1382
    searches \e{n}th-generation as well as first-generation children.
 
1383
 
 
1384
    If all this seems a bit complex for your needs, the simpler
 
1385
    child() function may be what you want.
 
1386
 
 
1387
    This somewhat contrived example disables all the buttons in this
 
1388
    window:
 
1389
 
 
1390
    \code
 
1391
        QList<QObject *> list = window()->queryList("QAbstractButton"));
 
1392
        foreach (QObject *obj, list)
 
1393
            static_cast<QAbstractButton *>(obj)->setEnabled(false);
 
1394
    \endcode
 
1395
 
 
1396
    \warning Delete the list as soon you have finished using it. The
 
1397
    list contains pointers that may become invalid at almost any time
 
1398
    without notice (as soon as the user closes a window you may have
 
1399
    dangling pointers, for example).
 
1400
 
 
1401
    \sa child() children(), parent(), inherits(), objectName(), QRegExp
 
1402
*/
 
1403
 
 
1404
QObjectList QObject::queryList(const char *inheritsClass,
 
1405
                                const char *objName,
 
1406
                                bool regexpMatch,
 
1407
                                bool recursiveSearch) const
 
1408
{
 
1409
    Q_D(const QObject);
 
1410
    QObjectList list;
 
1411
    bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
 
1412
#ifndef QT_NO_REGEXP
 
1413
    if (regexpMatch && objName) {                // regexp matching
 
1414
        QRegExp rx(QString::fromLatin1(objName));
 
1415
        objSearch(list, d->children, inheritsClass, onlyWidgets, 0, &rx, recursiveSearch);
 
1416
    } else
 
1417
#endif
 
1418
    {
 
1419
        objSearch(list, d->children, inheritsClass, onlyWidgets, objName, 0, recursiveSearch);
 
1420
    }
 
1421
    return list;
 
1422
}
 
1423
#endif
 
1424
 
 
1425
/*! \fn T *QObject::findChild(const QString &name) const
 
1426
 
 
1427
    Returns the child of this object that can be casted into type T and
 
1428
    that is called \a name, or 0 if there is no such object.
 
1429
    An empty string matches all object names.
 
1430
    The search is performed recursively.
 
1431
 
 
1432
    If there is more than one child matching the search, the most
 
1433
    direct ancestor is returned. If there are several direct
 
1434
    ancestors, it is undefined which one will be returned. In that
 
1435
    case, findChildren() should be used.
 
1436
 
 
1437
    This example returns a child \l{QPushButton} of \c{parentWidget}
 
1438
    named \c{"button1"}:
 
1439
 
 
1440
    \code
 
1441
        QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
 
1442
    \endcode
 
1443
 
 
1444
    This example returns a \l{QListWidget} child of \c{parentWidget}:
 
1445
 
 
1446
    \code
 
1447
        QListWidget *list = parentWidget->findChild<QListWidget *>();
 
1448
    \endcode
 
1449
 
 
1450
    \warning This function is not available with MSVC 6. Use
 
1451
    qFindChild() instead if you need to support that version of the
 
1452
    compiler.
 
1453
 
 
1454
    \sa findChildren(), qFindChild()
 
1455
*/
 
1456
 
 
1457
/*!
 
1458
    \fn QList<T> QObject::findChildren(const QString &name) const
 
1459
 
 
1460
    Returns all children of this object with the given \a name that can be
 
1461
    cast to type T, or an empty list if there are no such objects.
 
1462
    An empty string matches all object names.
 
1463
    The search is performed recursively.
 
1464
 
 
1465
    The following example shows how to find a list of child \l{QWidget}s of
 
1466
    the specified \c{parentWidget} named \c{widgetname}:
 
1467
 
 
1468
    \code
 
1469
        QList<QWidget *> widgets = parentWidget.findChildren<QWidget *>("widgetname");
 
1470
    \endcode
 
1471
 
 
1472
    This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
 
1473
 
 
1474
    \code
 
1475
        QList<QPushButton *> allPButtons = parentWidget.findChildren<QPushButton *>();
 
1476
    \endcode
 
1477
 
 
1478
    \warning This function is not available with MSVC 6. Use
 
1479
    qFindChildren() instead if you need to support that version of the
 
1480
    compiler.
 
1481
 
 
1482
    \sa findChild(), qFindChildren()
 
1483
*/
 
1484
 
 
1485
/*!
 
1486
    \fn QList<T> QObject::findChildren(const QRegExp &regExp) const
 
1487
    \overload
 
1488
 
 
1489
    Returns the children of this object that can be casted to type T
 
1490
    and that have names matching the regular expression \a regExp,
 
1491
    or an empty list if there are no such objects.
 
1492
    The search is performed recursively.
 
1493
 
 
1494
    \warning This function is not available with MSVC 6. Use
 
1495
    qFindChildren() instead if you need to support that version of the
 
1496
    compiler.
 
1497
*/
 
1498
 
 
1499
/*!
 
1500
    \fn T qFindChild(const QObject *obj, const QString &name)
 
1501
    \relates QObject
 
1502
 
 
1503
    This function is equivalent to
 
1504
    \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name). It is
 
1505
    provided as a work-around for MSVC 6, which doesn't support
 
1506
    member template functions.
 
1507
 
 
1508
    \sa QObject::findChild()
 
1509
*/
 
1510
 
 
1511
/*!
 
1512
    \fn QList<T> qFindChildren(const QObject *obj, const QString &name)
 
1513
    \relates QObject
 
1514
 
 
1515
    This function is equivalent to
 
1516
    \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name). It is
 
1517
    provided as a work-around for MSVC 6, which doesn't support
 
1518
    member template functions.
 
1519
 
 
1520
    \sa QObject::findChildren()
 
1521
*/
 
1522
 
 
1523
/*!
 
1524
    \fn QList<T> qFindChildren(const QObject *obj, const QRegExp &regExp)
 
1525
    \relates QObject
 
1526
    \overload
 
1527
 
 
1528
    This function is equivalent to
 
1529
    \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp). It is
 
1530
    provided as a work-around for MSVC 6, which doesn't support
 
1531
    member template functions.
 
1532
*/
 
1533
 
 
1534
/*!
 
1535
    \internal
 
1536
*/
 
1537
void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
 
1538
                         const QMetaObject &mo, QList<void*> *list)
 
1539
{
 
1540
    if (!parent || !list)
 
1541
        return;
 
1542
    const QObjectList &children = parent->children();
 
1543
    QObject *obj;
 
1544
    for (int i = 0; i < children.size(); ++i) {
 
1545
        obj = children.at(i);
 
1546
        if (mo.cast(obj)) {
 
1547
            if (re) {
 
1548
                if (re->indexIn(obj->objectName()) != -1)
 
1549
                    list->append(obj);
 
1550
            } else {
 
1551
                if (name.isNull() || obj->objectName() == name)
 
1552
                    list->append(obj);
 
1553
            }
 
1554
        }
 
1555
        qt_qFindChildren_helper(obj, name, re, mo, list);
 
1556
    }
 
1557
}
 
1558
 
 
1559
/*! \internal
 
1560
 */
 
1561
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo)
 
1562
{
 
1563
    if (!parent)
 
1564
        return 0;
 
1565
    const QObjectList &children = parent->children();
 
1566
    QObject *obj;
 
1567
    int i;
 
1568
    for (i = 0; i < children.size(); ++i) {
 
1569
        obj = children.at(i);
 
1570
        if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
 
1571
            return obj;
 
1572
    }
 
1573
    for (i = 0; i < children.size(); ++i) {
 
1574
        obj = qt_qFindChild_helper(children.at(i), name, mo);
 
1575
        if (obj)
 
1576
            return obj;
 
1577
    }
 
1578
    return 0;
 
1579
}
 
1580
 
 
1581
/*!
 
1582
    Makes the object a child of \a parent.
 
1583
 
 
1584
    \sa QWidget::setParent()
 
1585
*/
 
1586
 
 
1587
void QObject::setParent(QObject *parent)
 
1588
{
 
1589
    Q_D(QObject);
 
1590
    Q_ASSERT(!d->isWidget);
 
1591
    d->setParent_helper(parent);
 
1592
}
 
1593
 
 
1594
 
 
1595
void QObjectPrivate::setParent_helper(QObject *o)
 
1596
{
 
1597
    Q_Q(QObject);
 
1598
    if (o == parent)
 
1599
        return;
 
1600
    if (parent && !parent->d_func()->wasDeleted && parent->d_func()->children.removeAll(q)) {
 
1601
        if(sendChildEvents && parent->d_func()->receiveChildEvents) {
 
1602
            QChildEvent e(QEvent::ChildRemoved, q);
 
1603
            QCoreApplication::sendEvent(parent, &e);
 
1604
        }
 
1605
    }
 
1606
    parent = o;
 
1607
    if (parent) {
 
1608
        // object hierarchies are constrained to a single thread
 
1609
        Q_ASSERT_X(thread == parent->d_func()->thread, "QObject::setParent",
 
1610
                   "New parent must be in the same thread as the previous parent");
 
1611
        parent->d_func()->children.append(q);
 
1612
        if(sendChildEvents && parent->d_func()->receiveChildEvents) {
 
1613
            if (!isWidget) {
 
1614
                QChildEvent e(QEvent::ChildAdded, q);
 
1615
                QCoreApplication::sendEvent(parent, &e);
 
1616
#ifdef QT3_SUPPORT
 
1617
                QCoreApplication::postEvent(parent, new QChildEvent(QEvent::ChildInserted, q));
 
1618
#endif
 
1619
            }
 
1620
#ifdef QT3_SUPPORT
 
1621
            else {
 
1622
                QCoreApplication::postEvent(parent, new QChildEvent(QEvent::ChildInserted, q));
 
1623
            }
 
1624
#endif
 
1625
        }
 
1626
    }
 
1627
}
 
1628
 
 
1629
/*!
 
1630
    \fn void QObject::installEventFilter(QObject *filterObj)
 
1631
 
 
1632
    Installs an event filter \a filterObj on this object. For example:
 
1633
    \code
 
1634
    monitoredObj->installEventFilter(filterObj);
 
1635
    \endcode
 
1636
 
 
1637
    An event filter is an object that receives all events that are
 
1638
    sent to this object. The filter can either stop the event or
 
1639
    forward it to this object. The event filter \a filterObj receives
 
1640
    events via its eventFilter() function. The eventFilter() function
 
1641
    must return true if the event should be filtered, (i.e. stopped);
 
1642
    otherwise it must return false.
 
1643
 
 
1644
    If multiple event filters are installed on a single object, the
 
1645
    filter that was installed last is activated first.
 
1646
 
 
1647
    Here's a \c KeyPressEater class that eats the key presses of its
 
1648
    monitored objects:
 
1649
 
 
1650
    \code
 
1651
        class KeyPressEater : public QObject
 
1652
        {
 
1653
            Q_OBJECT
 
1654
            ...
 
1655
 
 
1656
        protected:
 
1657
            bool eventFilter(QObject *obj, QEvent *event);
 
1658
        };
 
1659
 
 
1660
        bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
 
1661
        {
 
1662
            if (event->type() == QEvent::KeyPress) {
 
1663
                QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
 
1664
                qDebug("Ate key press %d", keyEvent->key());
 
1665
                return true;
 
1666
            } else {
 
1667
                // standard event processing
 
1668
                return QObject::eventFilter(obj, event);
 
1669
            }
 
1670
        }
 
1671
    \endcode
 
1672
 
 
1673
    And here's how to install it on two widgets:
 
1674
 
 
1675
    \code
 
1676
        KeyPressEater *keyPressEater = new KeyPressEater(this);
 
1677
        QPushButton *pushButton = new QPushButton(this);
 
1678
        QListView *listView = new QListView(this);
 
1679
 
 
1680
        pushButton->installEventFilter(keyPressEater);
 
1681
        listView->installEventFilter(keyPressEater);
 
1682
    \endcode
 
1683
 
 
1684
    The QShortcut class, for example, uses this technique to intercept
 
1685
    shortcut key presses.
 
1686
 
 
1687
    \warning If you delete the receiver object in your eventFilter()
 
1688
    function, be sure to return true. If you return false, Qt sends
 
1689
    the event to the deleted object and the program will crash.
 
1690
 
 
1691
    \sa removeEventFilter(), eventFilter(), event()
 
1692
*/
 
1693
 
 
1694
void QObject::installEventFilter(QObject *obj)
 
1695
{
 
1696
    Q_D(QObject);
 
1697
    if (!obj)
 
1698
        return;
 
1699
    // clean up unused items in the list
 
1700
    d->eventFilters.removeAll((QObject*)0);
 
1701
    d->eventFilters.removeAll(obj);
 
1702
    d->eventFilters.prepend(obj);
 
1703
}
 
1704
 
 
1705
/*!
 
1706
    Removes an event filter object \a obj from this object. The
 
1707
    request is ignored if such an event filter has not been installed.
 
1708
 
 
1709
    All event filters for this object are automatically removed when
 
1710
    this object is destroyed.
 
1711
 
 
1712
    It is always safe to remove an event filter, even during event
 
1713
    filter activation (i.e. from the eventFilter() function).
 
1714
 
 
1715
    \sa installEventFilter(), eventFilter(), event()
 
1716
*/
 
1717
 
 
1718
void QObject::removeEventFilter(QObject *obj)
 
1719
{
 
1720
    Q_D(QObject);
 
1721
    d->eventFilters.removeAll(obj);
 
1722
}
 
1723
 
 
1724
 
 
1725
/*!
 
1726
    \fn QObject::destroyed(QObject *obj)
 
1727
 
 
1728
    This signal is emitted immediately before the object \a obj is
 
1729
    destroyed, and can not be blocked.
 
1730
 
 
1731
    All the objects's children are destroyed immediately after this
 
1732
    signal is emitted.
 
1733
 
 
1734
    \sa deleteLater(), QPointer
 
1735
*/
 
1736
 
 
1737
/*!
 
1738
    Performs a deferred deletion of this object.
 
1739
 
 
1740
    Instead of an immediate deletion this function schedules a
 
1741
    deferred delete event for processing when Qt returns to the main
 
1742
    event loop.
 
1743
 
 
1744
    \sa destroyed(), QPointer
 
1745
*/
 
1746
void QObject::deleteLater()
 
1747
{
 
1748
    QCoreApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));
 
1749
}
 
1750
 
 
1751
/*!
 
1752
    \fn QString QObject::tr(const char *sourceText, const char * comment)
 
1753
    \reentrant
 
1754
 
 
1755
    Returns a translated version of \a sourceText, or \a sourceText
 
1756
    itself if there is no appropriate translated version. The
 
1757
    translation context is Object with \a comment (0 by default).
 
1758
    All Object subclasses using the Q_OBJECT macro automatically have
 
1759
    a reimplementation of this function with the subclass name as
 
1760
    context.
 
1761
 
 
1762
    \warning This method is reentrant only if all translators are
 
1763
    installed \e before calling this method. Installing or removing
 
1764
    translators while performing translations is not supported. Doing
 
1765
    so will probably result in crashes or other undesirable behavior.
 
1766
 
 
1767
    \sa trUtf8(), QApplication::translate(), {Internationalization with Qt}
 
1768
*/
 
1769
 
 
1770
/*!
 
1771
    \fn QString QObject::trUtf8(const char *sourceText,
 
1772
                                 const char *comment)
 
1773
    \reentrant
 
1774
 
 
1775
    Returns a translated version of \a sourceText, or
 
1776
    QString::fromUtf8(\a sourceText) if there is no appropriate
 
1777
    version. It is otherwise identical to tr(\a sourceText, \a
 
1778
    comment).
 
1779
 
 
1780
    \warning This method is reentrant only if all translators are
 
1781
    installed \e before calling this method. Installing or removing
 
1782
    translators while performing translations is not supported. Doing
 
1783
    so will probably result in crashes or other undesirable behavior.
 
1784
 
 
1785
    \sa tr() QApplication::translate()
 
1786
*/
 
1787
 
 
1788
 
 
1789
 
 
1790
 
 
1791
/*****************************************************************************
 
1792
  Signals and slots
 
1793
 *****************************************************************************/
 
1794
 
 
1795
#ifndef QT_NO_DEBUG
 
1796
 
 
1797
static bool check_signal_macro(const QObject *sender, const char *signal,
 
1798
                                const char *func, const char *op)
 
1799
{
 
1800
    int sigcode = (int)(*signal) - '0';
 
1801
    if (sigcode != QSIGNAL_CODE) {
 
1802
        if (sigcode == QSLOT_CODE)
 
1803
            qWarning("Object::%s: Attempt to %s non-signal %s::%s",
 
1804
                     func, op, sender->metaObject()->className(), signal+1);
 
1805
        else
 
1806
            qWarning("Object::%s: Use the SIGNAL macro to %s %s::%s",
 
1807
                     func, op, sender->metaObject()->className(), signal);
 
1808
        return false;
 
1809
    }
 
1810
    return true;
 
1811
}
 
1812
 
 
1813
static bool check_method_code(int code, const QObject *object,
 
1814
                               const char *method, const char *func)
 
1815
{
 
1816
    if (code != QSLOT_CODE && code != QSIGNAL_CODE) {
 
1817
        qWarning("Object::%s: Use the SLOT or SIGNAL macro to "
 
1818
                 "%s %s::%s", func, func, object->metaObject()->className(), method);
 
1819
        return false;
 
1820
    }
 
1821
    return true;
 
1822
}
 
1823
 
 
1824
static void err_method_notfound(int code, const QObject *object,
 
1825
                                 const char *method, const char *func)
 
1826
{
 
1827
    const char *type = 0;
 
1828
    switch (code) {
 
1829
        case QSLOT_CODE:   type = "slot";   break;
 
1830
        case QSIGNAL_CODE: type = "signal"; break;
 
1831
    }
 
1832
    if (strchr(method,')') == 0)                // common typing mistake
 
1833
        qWarning("Object::%s: Parentheses expected, %s %s::%s",
 
1834
                 func, type, object->metaObject()->className(), method);
 
1835
    else
 
1836
        qWarning("Object::%s: No such %s %s::%s",
 
1837
                 func, type, object->metaObject()->className(), method);
 
1838
}
 
1839
 
 
1840
 
 
1841
static void err_info_about_objects(const char * func,
 
1842
                                    const QObject * sender,
 
1843
                                    const QObject * receiver)
 
1844
{
 
1845
    QString a = sender ? sender->objectName() : QString();
 
1846
    QString b = receiver ? receiver->objectName() : QString();
 
1847
    if (!a.isEmpty())
 
1848
        qWarning("Object::%s:  (sender name:   '%s')", func, a.toLocal8Bit().data());
 
1849
    if (!b.isEmpty())
 
1850
        qWarning("Object::%s:  (receiver name: '%s')", func, b.toLocal8Bit().data());
 
1851
}
 
1852
 
 
1853
#endif // !QT_NO_DEBUG
 
1854
 
 
1855
/*!
 
1856
    Returns a pointer to the object that sent the signal, if called in
 
1857
    a slot activated by a signal; otherwise it returns 0. The pointer
 
1858
    is valid only during the execution of the slot that calls this
 
1859
    function.
 
1860
 
 
1861
    The pointer returned by this function becomes invalid if the
 
1862
    sender is destroyed, or if the slot is disconnected from the
 
1863
    sender's signal.
 
1864
 
 
1865
    \warning This function violates the object-oriented principle of
 
1866
     modularity. However, getting access to the sender might be useful
 
1867
     when many signals are connected to a single slot. The sender is
 
1868
     undefined if the slot is called as a normal C++ function.
 
1869
*/
 
1870
 
 
1871
QObject *QObject::sender() const
 
1872
{
 
1873
    Q_D(const QObject);
 
1874
    QConnectionList * const list = ::connectionList();
 
1875
    if (!list)
 
1876
        return 0;
 
1877
 
 
1878
    QReadLocker locker(&list->lock);
 
1879
    QConnectionList::Hash::const_iterator it = list->sendersHash.find(d->currentSender);
 
1880
    const QConnectionList::Hash::const_iterator end = list->sendersHash.constEnd();
 
1881
 
 
1882
    // Return 0 if d->currentSender isn't in the senders hash (it has been destroyed?)
 
1883
    if (it == end)
 
1884
        return 0;
 
1885
 
 
1886
    // Only return d->currentSender if it's actually connected to "this"
 
1887
    for (; it != end && it.key() == d->currentSender; ++it) {
 
1888
        const int at = it.value();
 
1889
        const QConnection &c = list->connections.at(at);
 
1890
 
 
1891
        if (c.receiver == this)
 
1892
            return d->currentSender;
 
1893
    }
 
1894
 
 
1895
    return 0;
 
1896
}
 
1897
 
 
1898
/*!
 
1899
    Returns the number of receivers connect to the \a signal.
 
1900
 
 
1901
    When calling this function, you can use the \c SIGNAL() macro to
 
1902
    pass a specific signal:
 
1903
 
 
1904
    \code
 
1905
        if (receivers(SIGNAL(valueChanged(QByteArray))) > 0) {
 
1906
            QByteArray data;
 
1907
            get_the_value(&data);       // expensive operation
 
1908
            emit valueChanged(data);
 
1909
        }
 
1910
    \endcode
 
1911
 
 
1912
    As the code snippet above illustrates, you can use this function
 
1913
    to avoid emitting a signal that nobody listens to.
 
1914
 
 
1915
    \warning This function violates the object-oriented principle of
 
1916
    modularity. However, it might be useful when you need to perform
 
1917
    expensive initialization only if something is connected to a
 
1918
    signal.
 
1919
*/
 
1920
 
 
1921
int QObject::receivers(const char *signal) const
 
1922
{
 
1923
    int receivers = 0;
 
1924
    if (signal) {
 
1925
        QByteArray signal_name = QMetaObject::normalizedSignature(signal);
 
1926
        signal = signal_name;
 
1927
#ifndef QT_NO_DEBUG
 
1928
        if (!check_signal_macro(this, signal, "receivers", "bind"))
 
1929
            return 0;
 
1930
#endif
 
1931
        signal++; // skip code
 
1932
        const QMetaObject *smeta = this->metaObject();
 
1933
        int signal_index = smeta->indexOfSignal(signal);
 
1934
        if (signal_index < 0) {
 
1935
#ifndef QT_NO_DEBUG
 
1936
            err_method_notfound(QSIGNAL_CODE, this, signal, "receivers");
 
1937
#endif
 
1938
            return false;
 
1939
        }
 
1940
        QConnectionList *list = ::connectionList();
 
1941
        QReadLocker locker(&list->lock);
 
1942
        QHash<const QObject *, int>::const_iterator i = list->sendersHash.find(this);
 
1943
        while (i != list->sendersHash.constEnd() && i.key() == this) {
 
1944
            if (list->connections.at(i.value()).signal == signal_index)
 
1945
                ++receivers;
 
1946
            ++i;
 
1947
        }
 
1948
    }
 
1949
    return receivers;
 
1950
}
 
1951
 
 
1952
/*!
 
1953
    \threadsafe
 
1954
 
 
1955
    Creates a connection of the given \a type from the \a signal in
 
1956
    the \a sender object to the \a method in the \a receiver object.
 
1957
    Returns true if the connection succeeds; otherwise returns false.
 
1958
 
 
1959
    You must use the \c SIGNAL() and \c SLOT() macros when specifying
 
1960
    the \a signal and the \a method, for example:
 
1961
 
 
1962
    \code
 
1963
        QLabel *label = new QLabel;
 
1964
        QScrollBar *scrollBar = new QScrollBar;
 
1965
        QObject::connect(scroll, SIGNAL(valueChanged(int)),
 
1966
                         label,  SLOT(setNum(int)));
 
1967
    \endcode
 
1968
 
 
1969
    This example ensures that the label always displays the current
 
1970
    scroll bar value. Note that the signal and slots parameters must not
 
1971
    contain any variable names, only the type. E.g. the following would
 
1972
    not work and return false:
 
1973
 
 
1974
    \code
 
1975
        // WRONG
 
1976
        QObject::connect(scroll, SIGNAL(valueChanged(int value)),
 
1977
                         label, SLOT(setNum(int value)));
 
1978
    \endcode
 
1979
 
 
1980
    A signal can also be connected to another signal:
 
1981
 
 
1982
    \code
 
1983
        class MyWidget : public QWidget
 
1984
        {
 
1985
            Q_OBJECT
 
1986
 
 
1987
        public:
 
1988
            MyWidget();
 
1989
 
 
1990
        signals:
 
1991
            void buttonClicked();
 
1992
 
 
1993
        private:
 
1994
            QPushButton *myButton;
 
1995
        };
 
1996
 
 
1997
        MyWidget::MyWidget()
 
1998
        {
 
1999
            myButton = new QPushButton(this);
 
2000
            connect(myButton, SIGNAL(clicked()),
 
2001
                    this, SIGNAL(buttonClicked()));
 
2002
        }
 
2003
    \endcode
 
2004
 
 
2005
    In this example, the \c MyWidget constructor relays a signal from
 
2006
    a private member variable, and makes it available under a name
 
2007
    that relates to \c MyWidget.
 
2008
 
 
2009
    A signal can be connected to many slots and signals. Many signals
 
2010
    can be connected to one slot.
 
2011
 
 
2012
    If a signal is connected to several slots, the slots are activated
 
2013
    in an arbitrary order when the signal is emitted.
 
2014
 
 
2015
    The function returns true if it successfully connects the signal
 
2016
    to the slot. It will return false if it cannot create the
 
2017
    connection, for example, if QObject is unable to verify the
 
2018
    existence of either \a signal or \a method, or if their signatures
 
2019
    aren't compatible.
 
2020
 
 
2021
    A signal is emitted for every connection you make, so if you
 
2022
    duplicate a connection, two signals will be emitted. You can
 
2023
    always break a connection using disconnect().
 
2024
 
 
2025
    \sa disconnect()
 
2026
*/
 
2027
 
 
2028
bool QObject::connect(const QObject *sender, const char *signal,
 
2029
                      const QObject *receiver, const char *method,
 
2030
                      Qt::ConnectionType type)
 
2031
{
 
2032
#ifndef QT_NO_DEBUG
 
2033
    bool warnCompat = true;
 
2034
#endif
 
2035
    if (type == Qt::AutoCompatConnection) {
 
2036
        type = Qt::AutoConnection;
 
2037
#ifndef QT_NO_DEBUG
 
2038
        warnCompat = false;
 
2039
#endif
 
2040
    }
 
2041
 
 
2042
    if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
 
2043
#ifndef QT_NO_DEBUG
 
2044
        qWarning("Object::connect: Cannot connect %s::%s to %s::%s",
 
2045
                 sender ? sender->metaObject()->className() : "(null)",
 
2046
                 signal ? signal+1 : "(null)",
 
2047
                 receiver ? receiver->metaObject()->className() : "(null)",
 
2048
                 method ? method+1 : "(null)");
 
2049
#endif
 
2050
        return false;
 
2051
    }
 
2052
    QByteArray tmp_signal_name;
 
2053
 
 
2054
#ifndef QT_NO_DEBUG
 
2055
    if (!check_signal_macro(sender, signal, "connect", "bind"))
 
2056
        return false;
 
2057
#endif
 
2058
    const QMetaObject *smeta = sender->metaObject();
 
2059
    ++signal; //skip code
 
2060
    int signal_index = smeta->indexOfSignal(signal);
 
2061
    if (signal_index < 0) {
 
2062
        // check for normalized signatures
 
2063
        tmp_signal_name = QMetaObject::normalizedSignature(signal).prepend(*(signal - 1));
 
2064
        signal = tmp_signal_name.constData() + 1;
 
2065
        signal_index = smeta->indexOfSignal(signal);
 
2066
        if (signal_index < 0) {
 
2067
#ifndef QT_NO_DEBUG
 
2068
            err_method_notfound(QSIGNAL_CODE, sender, signal, "connect");
 
2069
            err_info_about_objects("connect", sender, receiver);
 
2070
#endif
 
2071
            return false;
 
2072
        }
 
2073
    }
 
2074
 
 
2075
    QByteArray tmp_method_name;
 
2076
    int membcode = method[0] - '0';
 
2077
 
 
2078
#ifndef QT_NO_DEBUG
 
2079
    if (!check_method_code(membcode, receiver, method, "connect"))
 
2080
        return false;
 
2081
#endif
 
2082
    ++method; // skip code
 
2083
 
 
2084
    const QMetaObject *rmeta = receiver->metaObject();
 
2085
    int method_index = -1;
 
2086
    switch (membcode) {
 
2087
    case QSLOT_CODE:
 
2088
        method_index = rmeta->indexOfSlot(method);
 
2089
        break;
 
2090
    case QSIGNAL_CODE:
 
2091
        method_index = rmeta->indexOfSignal(method);
 
2092
        break;
 
2093
    }
 
2094
    if (method_index < 0) {
 
2095
        // check for normalized methods
 
2096
        tmp_method_name = QMetaObject::normalizedSignature(method);
 
2097
        method = tmp_method_name.constData();
 
2098
        switch (membcode) {
 
2099
        case QSLOT_CODE:
 
2100
            method_index = rmeta->indexOfSlot(method);
 
2101
            break;
 
2102
        case QSIGNAL_CODE:
 
2103
            method_index = rmeta->indexOfSignal(method);
 
2104
            break;
 
2105
        }
 
2106
    }
 
2107
 
 
2108
    if (method_index < 0) {
 
2109
#ifndef QT_NO_DEBUG
 
2110
        err_method_notfound(membcode, receiver, method, "connect");
 
2111
        err_info_about_objects("connect", sender, receiver);
 
2112
#endif
 
2113
        return false;
 
2114
    }
 
2115
#ifndef QT_NO_DEBUG
 
2116
    if (!QMetaObject::checkConnectArgs(signal, method)) {
 
2117
        qWarning("Object::connect: Incompatible sender/receiver arguments"
 
2118
                 "\n\t%s::%s --> %s::%s",
 
2119
                 sender->metaObject()->className(), signal,
 
2120
                 receiver->metaObject()->className(), method);
 
2121
        return false;
 
2122
    }
 
2123
#endif
 
2124
 
 
2125
    int *types = 0;
 
2126
    if (type == Qt::QueuedConnection && !(types = ::queuedConnectionTypes(signal)))
 
2127
        return false;
 
2128
 
 
2129
#ifndef QT_NO_DEBUG
 
2130
    {
 
2131
        QMetaMethod smethod = smeta->method(signal_index), rmethod;
 
2132
        switch (membcode) {
 
2133
        case QSLOT_CODE:
 
2134
            rmethod = rmeta->method(method_index);
 
2135
            break;
 
2136
        case QSIGNAL_CODE:
 
2137
            rmethod = rmeta->method(method_index);
 
2138
            break;
 
2139
        }
 
2140
        if (warnCompat) {
 
2141
            if(smethod.attributes() & QMetaMethod::Compatibility) {
 
2142
                if (!(rmethod.attributes() & QMetaMethod::Compatibility))
 
2143
                    qWarning("Object::connect: Connecting from COMPAT signal (%s::%s).", smeta->className(), signal);
 
2144
            } else if(rmethod.attributes() & QMetaMethod::Compatibility && membcode != QSIGNAL_CODE) {
 
2145
                qWarning("Object::connect: Connecting from %s::%s to COMPAT slot (%s::%s).",
 
2146
                         smeta->className(), signal, rmeta->className(), method);
 
2147
            }
 
2148
        }
 
2149
        switch(rmethod.access()) {
 
2150
        case QMetaMethod::Private:
 
2151
            break;
 
2152
        case QMetaMethod::Protected:
 
2153
            break;
 
2154
        default:
 
2155
            break;
 
2156
        }
 
2157
    }
 
2158
#endif
 
2159
    QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
 
2160
    const_cast<QObject*>(sender)->connectNotify(signal - 1);
 
2161
    return true;
 
2162
}
 
2163
 
 
2164
 
 
2165
/*!
 
2166
    \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
 
2167
    \overload
 
2168
    \threadsafe
 
2169
 
 
2170
    Connects \a signal from the \a sender object to this object's \a
 
2171
    method.
 
2172
 
 
2173
    Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
 
2174
 
 
2175
    \sa disconnect()
 
2176
*/
 
2177
 
 
2178
/*!
 
2179
    \threadsafe
 
2180
 
 
2181
    Disconnects \a signal in object \a sender from \a method in object
 
2182
    \a receiver.
 
2183
 
 
2184
    A signal-slot connection is removed when either of the objects
 
2185
    involved are destroyed.
 
2186
 
 
2187
    disconnect() is typically used in three ways, as the following
 
2188
    examples demonstrate.
 
2189
    \list 1
 
2190
    \i Disconnect everything connected to an object's signals:
 
2191
 
 
2192
       \code
 
2193
       disconnect(myObject, 0, 0, 0);
 
2194
       \endcode
 
2195
 
 
2196
       equivalent to the non-static overloaded function
 
2197
 
 
2198
       \code
 
2199
       myObject->disconnect();
 
2200
       \endcode
 
2201
 
 
2202
    \i Disconnect everything connected to a specific signal:
 
2203
 
 
2204
       \code
 
2205
       disconnect(myObject, SIGNAL(mySignal()), 0, 0);
 
2206
       \endcode
 
2207
 
 
2208
       equivalent to the non-static overloaded function
 
2209
 
 
2210
       \code
 
2211
       myObject->disconnect(SIGNAL(mySignal()));
 
2212
       \endcode
 
2213
 
 
2214
    \i Disconnect a specific receiver:
 
2215
 
 
2216
       \code
 
2217
       disconnect(myObject, 0, myReceiver, 0);
 
2218
       \endcode
 
2219
 
 
2220
       equivalent to the non-static overloaded function
 
2221
 
 
2222
       \code
 
2223
       myObject->disconnect(myReceiver);
 
2224
       \endcode
 
2225
 
 
2226
    \endlist
 
2227
 
 
2228
    0 may be used as a wildcard, meaning "any signal", "any receiving
 
2229
    object", or "any slot in the receiving object", respectively.
 
2230
 
 
2231
    The \a sender may never be 0. (You cannot disconnect signals from
 
2232
    more than one object in a single call.)
 
2233
 
 
2234
    If \a signal is 0, it disconnects \a receiver and \a method from
 
2235
    any signal. If not, only the specified signal is disconnected.
 
2236
 
 
2237
    If \a receiver is 0, it disconnects anything connected to \a
 
2238
    signal. If not, slots in objects other than \a receiver are not
 
2239
    disconnected.
 
2240
 
 
2241
    If \a method is 0, it disconnects anything that is connected to \a
 
2242
    receiver. If not, only slots named \a method will be disconnected,
 
2243
    and all other slots are left alone. The \a method must be 0 if \a
 
2244
    receiver is left out, so you cannot disconnect a
 
2245
    specifically-named slot on all objects.
 
2246
 
 
2247
    \sa connect()
 
2248
*/
 
2249
bool QObject::disconnect(const QObject *sender, const char *signal,
 
2250
                         const QObject *receiver, const char *method)
 
2251
{
 
2252
    if (sender == 0 || (receiver == 0 && method != 0)) {
 
2253
        qWarning("Object::disconnect: Unexpected null parameter");
 
2254
        return false;
 
2255
    }
 
2256
 
 
2257
    QByteArray signal_name;
 
2258
#ifndef QT_NO_DEBUG
 
2259
    bool signal_found = false;
 
2260
#endif
 
2261
    if (signal) {
 
2262
        signal_name = QMetaObject::normalizedSignature(signal);
 
2263
        signal = signal_name;
 
2264
#ifndef QT_NO_DEBUG
 
2265
        if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
 
2266
            return false;
 
2267
#endif
 
2268
        signal++; // skip code
 
2269
    }
 
2270
 
 
2271
    QByteArray method_name;
 
2272
#ifndef QT_NO_DEBUG
 
2273
    int membcode = -1;
 
2274
#endif
 
2275
    bool method_found = false;
 
2276
    if (method) {
 
2277
        method_name = QMetaObject::normalizedSignature(method);
 
2278
        method = method_name;
 
2279
#ifndef QT_NO_DEBUG
 
2280
        membcode = method[0] - '0';
 
2281
        if (!check_method_code(membcode, receiver, method, "disconnect"))
 
2282
            return false;
 
2283
#endif
 
2284
        method++; // skip code
 
2285
    }
 
2286
 
 
2287
    /* We now iterate through all the sender's and receiver's meta
 
2288
     * objects in order to also disconnect possibly shadowed signals
 
2289
     * and slots with the same signature.
 
2290
    */
 
2291
    bool res = false;
 
2292
    const QMetaObject *smeta = sender->metaObject();
 
2293
    do {
 
2294
        int signal_index = -1;
 
2295
        if (signal) {
 
2296
            signal_index = smeta->indexOfSignal(signal);
 
2297
            if (signal_index < smeta->methodOffset())
 
2298
                continue;
 
2299
#ifndef QT_NO_DEBUG
 
2300
            signal_found = true;
 
2301
#endif
 
2302
        }
 
2303
 
 
2304
        if (!method) {
 
2305
            res |= QMetaObject::disconnect(sender, signal_index, receiver, -1);
 
2306
        } else {
 
2307
            const QMetaObject *rmeta = receiver->metaObject();
 
2308
            do {
 
2309
                int method_index = rmeta->indexOfMethod(method);
 
2310
                if (method_index >= 0)
 
2311
                    while (method_index < rmeta->methodOffset())
 
2312
                            rmeta = rmeta->superClass();
 
2313
                if (method_index < 0)
 
2314
                    break;
 
2315
                res |= QMetaObject::disconnect(sender, signal_index, receiver, method_index);
 
2316
                method_found = true;
 
2317
            } while ((rmeta = rmeta->superClass()));
 
2318
        }
 
2319
    } while (signal && (smeta = smeta->superClass()));
 
2320
 
 
2321
#ifndef QT_NO_DEBUG
 
2322
    if (signal && !signal_found) {
 
2323
        err_method_notfound(QSIGNAL_CODE, sender, signal, "disconnect");
 
2324
        err_info_about_objects("disconnect", sender, receiver);
 
2325
    } else if (method && !method_found) {
 
2326
        err_method_notfound(membcode, receiver, method, "disconnect");
 
2327
        err_info_about_objects("disconnect", sender, receiver);
 
2328
    }
 
2329
#endif
 
2330
    if (res)
 
2331
        const_cast<QObject*>(sender)->disconnectNotify(signal - 1);
 
2332
    return res;
 
2333
}
 
2334
 
 
2335
 
 
2336
/*!
 
2337
    \threadsafe
 
2338
 
 
2339
    \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method)
 
2340
    \overload
 
2341
 
 
2342
    Disconnects \a signal from \a method of \a receiver.
 
2343
 
 
2344
    A signal-slot connection is removed when either of the objects
 
2345
    involved are destroyed.
 
2346
*/
 
2347
 
 
2348
/*!
 
2349
    \fn bool QObject::disconnect(const QObject *receiver, const char *method)
 
2350
    \overload
 
2351
 
 
2352
    Disconnects all signals in this object from \a receiver's \a
 
2353
    method.
 
2354
 
 
2355
    A signal-slot connection is removed when either of the objects
 
2356
    involved are destroyed.
 
2357
*/
 
2358
 
 
2359
 
 
2360
/*!
 
2361
    \fn void QObject::connectNotify(const char *signal)
 
2362
 
 
2363
    This virtual function is called when something has been connected
 
2364
    to \a signal in this object.
 
2365
 
 
2366
    If you want to compare \a signal with a specific signal, use
 
2367
    QLatin1String and the \c SIGNAL() macro as follows:
 
2368
 
 
2369
    \code
 
2370
        if (QLatin1String(signal) == SIGNAL(valueChanged(int))) {
 
2371
            // signal is valueChanged(int)
 
2372
        }
 
2373
    \endcode
 
2374
 
 
2375
    If the signal contains multiple parameters or parameters that
 
2376
    contain spaces, call QMetaObject::normalizedSignature() on
 
2377
    the result of the \c SIGNAL() macro.
 
2378
 
 
2379
    \warning This function violates the object-oriented principle of
 
2380
    modularity. However, it might be useful when you need to perform
 
2381
    expensive initialization only if something is connected to a
 
2382
    signal.
 
2383
 
 
2384
    \sa connect(), disconnectNotify()
 
2385
*/
 
2386
 
 
2387
void QObject::connectNotify(const char *)
 
2388
{
 
2389
}
 
2390
 
 
2391
/*!
 
2392
    \fn void QObject::disconnectNotify(const char *signal)
 
2393
 
 
2394
    This virtual function is called when something has been
 
2395
    disconnected from \a signal in this object.
 
2396
 
 
2397
    See connectNotify() for an example of how to compare
 
2398
    \a signal with a specific signal.
 
2399
 
 
2400
    \warning This function violates the object-oriented principle of
 
2401
    modularity. However, it might be useful for optimizing access to
 
2402
    expensive resources.
 
2403
 
 
2404
    \sa disconnect(), connectNotify()
 
2405
*/
 
2406
 
 
2407
void QObject::disconnectNotify(const char *)
 
2408
{
 
2409
}
 
2410
 
 
2411
/*!\internal
 
2412
 
 
2413
  \a types is a 0-terminated vector of meta types for queued
 
2414
  connections.
 
2415
*/
 
2416
bool QMetaObject::connect(const QObject *sender, int signal_index,
 
2417
                          const QObject *receiver, int method_index, int type, int *types)
 
2418
{
 
2419
    QConnectionList *list = ::connectionList();
 
2420
    if (!list)
 
2421
        return false;
 
2422
    QWriteLocker locker(&list->lock);
 
2423
    list->addConnection(const_cast<QObject *>(sender), signal_index,
 
2424
                        const_cast<QObject *>(receiver), method_index, type, types);
 
2425
    return true;
 
2426
}
 
2427
 
 
2428
 
 
2429
/*!\internal
 
2430
 */
 
2431
bool QMetaObject::disconnect(const QObject *sender, int signal_index,
 
2432
                             const QObject *receiver, int method_index)
 
2433
{
 
2434
    if (!sender)
 
2435
        return false;
 
2436
    QConnectionList *list = ::connectionList();
 
2437
    if (!list)
 
2438
        return false;
 
2439
    QWriteLocker locker(&list->lock);
 
2440
    return list->removeConnection(const_cast<QObject*>(sender), signal_index,
 
2441
                                  const_cast<QObject*>(receiver), method_index);
 
2442
}
 
2443
 
 
2444
/*!\internal
 
2445
 */
 
2446
void QMetaObject::connectSlotsByName(QObject *o)
 
2447
{
 
2448
    if (!o)
 
2449
        return;
 
2450
    const QMetaObject *mo = o->metaObject();
 
2451
    Q_ASSERT(mo);
 
2452
    const QObjectList list = qFindChildren<QObject *>(o, QString());
 
2453
    for (int i = 0; i < mo->methodCount(); ++i) {
 
2454
        const char *slot = mo->method(i).signature();
 
2455
        Q_ASSERT(slot);
 
2456
        if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
 
2457
            continue;
 
2458
        bool foundIt = false;
 
2459
        for(int j = 0; j < list.count(); ++j) {
 
2460
            const QObject *co = list.at(j);
 
2461
            QByteArray objName = co->objectName().toAscii();
 
2462
            int len = objName.length();
 
2463
            if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
 
2464
                continue;
 
2465
            const QMetaObject *smo = co->metaObject();
 
2466
            int sigIndex = smo->indexOfMethod(slot + len + 4);
 
2467
            if (sigIndex < 0) { // search for compatible signals
 
2468
                int slotlen = qstrlen(slot + len + 4) - 1;
 
2469
                for (int k = 0; k < co->metaObject()->methodCount(); ++k) {
 
2470
                    if (smo->method(k).methodType() != QMetaMethod::Signal)
 
2471
                        continue;
 
2472
 
 
2473
                    if (!qstrncmp(smo->method(k).signature(), slot + len + 4, slotlen)) {
 
2474
                        sigIndex = k;
 
2475
                        break;
 
2476
                    }
 
2477
                }
 
2478
            }
 
2479
            if (sigIndex < 0)
 
2480
                continue;
 
2481
            if (QMetaObject::connect(co, sigIndex, o, i)) {
 
2482
                foundIt = true;
 
2483
                break;
 
2484
            }
 
2485
        }
 
2486
        if (!foundIt)
 
2487
            qWarning("QMetaObject::connectSlotsByName(): No matching signal for %s", slot);
 
2488
    }
 
2489
}
 
2490
 
 
2491
static void queued_activate(QObject *obj, const QConnection &c, void **argv)
 
2492
{
 
2493
    if (!c.types && c.types != &DIRECT_CONNECTION_ONLY) {
 
2494
        QMetaMethod m = obj->metaObject()->method(c.signal);
 
2495
        QConnection &x = const_cast<QConnection &>(c);
 
2496
        x.types = ::queuedConnectionTypes(m.signature());
 
2497
        if (!x.types) // cannot queue arguments
 
2498
            x.types = &DIRECT_CONNECTION_ONLY;
 
2499
    }
 
2500
    if (c.types == &DIRECT_CONNECTION_ONLY) // cannot activate
 
2501
        return;
 
2502
    int nargs = 1; // include return type
 
2503
    while (c.types[nargs-1]) { ++nargs; }
 
2504
    int *types = (int *) qMalloc(nargs*sizeof(int));
 
2505
    void **args = (void **) qMalloc(nargs*sizeof(void *));
 
2506
    types[0] = 0; // return type
 
2507
    args[0] = 0; // return value
 
2508
    for (int n = 1; n < nargs; ++n)
 
2509
        args[n] = QMetaType::construct((types[n] = c.types[n-1]), argv[n]);
 
2510
    QCoreApplication::postEvent(c.receiver, new QMetaCallEvent(c.method, nargs, types, args));
 
2511
}
 
2512
 
 
2513
/*!\internal
 
2514
 */
 
2515
void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
 
2516
{
 
2517
    if (sender->d_func()->blockSig)
 
2518
        return;
 
2519
    QConnectionList * const list = ::connectionList();
 
2520
    if (!list)
 
2521
        return;
 
2522
    QReadLocker locker(&list->lock);
 
2523
    QConnectionList::Hash::const_iterator it = list->sendersHash.find(sender);
 
2524
    const QConnectionList::Hash::const_iterator end = list->sendersHash.constEnd();
 
2525
    if (it == end)
 
2526
        return;
 
2527
 
 
2528
    list->invariant.ref();
 
2529
 
 
2530
    void *empty_argv[] = { 0 };
 
2531
    QThread * const currentThread = QThread::currentThread();
 
2532
    const int currentQThreadId = currentThread ? QThreadData::get(currentThread)->id : -1;
 
2533
 
 
2534
    if (qt_signal_spy_callback_set.signal_begin_callback != 0)
 
2535
        qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index,
 
2536
                                                         argv ? argv : empty_argv);
 
2537
 
 
2538
    QVarLengthArray<int> connections;
 
2539
    for (; it != end && it.key() == sender; ++it)
 
2540
        connections.append(it.value());
 
2541
    for (int i = 0; i < connections.size(); ++i) {
 
2542
        const int at = connections.constData()[connections.size() - (i + 1)];
 
2543
        QConnectionList * const list = ::connectionList();
 
2544
        const QConnection &c = list->connections.at(at);
 
2545
        if (!c.receiver || c.signal != signal_index)
 
2546
            continue;
 
2547
 
 
2548
        // determine if this connection should be sent immediately or
 
2549
        // put into the event queue
 
2550
        if ((c.type == Qt::AutoConnection
 
2551
             && (currentQThreadId != sender->d_func()->thread
 
2552
                 || c.receiver->d_func()->thread != sender->d_func()->thread))
 
2553
            || (c.type == Qt::QueuedConnection)) {
 
2554
            ::queued_activate(sender, c, argv);
 
2555
            continue;
 
2556
        }
 
2557
 
 
2558
        const int method = c.method;
 
2559
        QObject * const previousSender = c.receiver->d_func()->currentSender;
 
2560
        c.receiver->d_func()->currentSender = sender;
 
2561
        list->lock.unlock();
 
2562
 
 
2563
        if (qt_signal_spy_callback_set.slot_begin_callback != 0)
 
2564
            qt_signal_spy_callback_set.slot_begin_callback(c.receiver, method, argv ? argv : empty_argv);
 
2565
 
 
2566
#if defined(QT_NO_EXCEPTIONS)
 
2567
        c.receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
 
2568
#else
 
2569
        try {
 
2570
            c.receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
 
2571
        } catch (...) {
 
2572
            list->lock.lockForRead();
 
2573
            if (c.receiver) {
 
2574
                c.receiver->d_func()->currentSender = previousSender;
 
2575
                throw;
 
2576
            }
 
2577
        }
 
2578
#endif
 
2579
 
 
2580
        if (qt_signal_spy_callback_set.slot_end_callback != 0)
 
2581
            qt_signal_spy_callback_set.slot_end_callback(c.receiver, method);
 
2582
 
 
2583
        list->lock.lockForRead();
 
2584
        if (c.receiver)
 
2585
            c.receiver->d_func()->currentSender = previousSender;
 
2586
    }
 
2587
 
 
2588
    if (qt_signal_spy_callback_set.signal_end_callback != 0)
 
2589
        qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
 
2590
 
 
2591
    list->invariant.deref();
 
2592
}
 
2593
 
 
2594
/*!\internal
 
2595
 */
 
2596
void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
 
2597
                           void **argv)
 
2598
{
 
2599
    activate(sender, m->methodOffset() + local_signal_index, argv);
 
2600
}
 
2601
 
 
2602
/*****************************************************************************
 
2603
  Properties
 
2604
 *****************************************************************************/
 
2605
 
 
2606
#ifndef QT_NO_PROPERTIES
 
2607
 
 
2608
/*!
 
2609
  Sets the value of the obj1ect's \a name property to \a value.
 
2610
 
 
2611
  Returns true if the operation was successful; otherwise returns
 
2612
  false.
 
2613
 
 
2614
  Information about all available properties is provided through the
 
2615
  metaObject().
 
2616
 
 
2617
  \sa property(), metaObject()
 
2618
*/
 
2619
bool QObject::setProperty(const char *name, const QVariant &value)
 
2620
{
 
2621
    const QMetaObject* meta = metaObject();
 
2622
    if (!name || !meta)
 
2623
        return false;
 
2624
 
 
2625
    int id = meta->indexOfProperty(name);
 
2626
    QMetaProperty p = meta->property(id);
 
2627
#ifndef QT_NO_DEBUG
 
2628
    if (!p.isWritable())
 
2629
        qWarning("%s::setProperty(\"%s\", value) failed: property invalid,"
 
2630
                 " read-only or does not exist", metaObject()->className(), name);
 
2631
#endif
 
2632
    return p.write(this, value);
 
2633
}
 
2634
 
 
2635
/*!
 
2636
  Returns the value of the object's \a name property.
 
2637
 
 
2638
  If no such property exists, the returned variant is invalid.
 
2639
 
 
2640
  Information about all available properties is provided through the
 
2641
  metaObject().
 
2642
 
 
2643
  \sa setProperty(), QVariant::isValid(), metaObject()
 
2644
*/
 
2645
QVariant QObject::property(const char *name) const
 
2646
{
 
2647
    const QMetaObject* meta = metaObject();
 
2648
    if (!name || !meta)
 
2649
        return QVariant();
 
2650
 
 
2651
    int id = meta->indexOfProperty(name);
 
2652
    QMetaProperty p = meta->property(id);
 
2653
#ifndef QT_NO_DEBUG
 
2654
    if (!p.isReadable())
 
2655
        qWarning("%s::property(\"%s\") failed:"
 
2656
                 " property invalid or does not exist",
 
2657
                 metaObject()->className(), name);
 
2658
#endif
 
2659
    return p.read(this);
 
2660
}
 
2661
 
 
2662
#endif // QT_NO_PROPERTIES
 
2663
 
 
2664
 
 
2665
/*****************************************************************************
 
2666
  QObject debugging output routines.
 
2667
 *****************************************************************************/
 
2668
 
 
2669
static void dumpRecursive(int level, QObject *object)
 
2670
{
 
2671
#if defined(QT_DEBUG)
 
2672
    if (object) {
 
2673
        QByteArray buf;
 
2674
        buf.fill('\t', level/2);
 
2675
        if (level % 2)
 
2676
            buf += "    ";
 
2677
        QString name = object->objectName();
 
2678
        QString flags = QLatin1String("");
 
2679
#if 0
 
2680
        if (qApp->focusWidget() == object)
 
2681
            flags += 'F';
 
2682
        if (object->isWidgetType()) {
 
2683
            QWidget * w = (QWidget *)object;
 
2684
            if (w->isVisible()) {
 
2685
                QString t("<%1,%2,%3,%4>");
 
2686
                flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height());
 
2687
            } else {
 
2688
                flags += 'I';
 
2689
            }
 
2690
        }
 
2691
#endif
 
2692
        qDebug("%s%s::%s %s", (const char*)buf, object->metaObject()->className(), name.toLocal8Bit().data(),
 
2693
               flags.toLatin1().data());
 
2694
        QObjectList children = object->children();
 
2695
        if (!children.isEmpty()) {
 
2696
            for (int i = 0; i < children.size(); ++i)
 
2697
                dumpRecursive(level+1, children.at(i));
 
2698
        }
 
2699
    }
 
2700
#else
 
2701
    Q_UNUSED(level)
 
2702
        Q_UNUSED(object)
 
2703
#endif
 
2704
}
 
2705
 
 
2706
/*!
 
2707
    Dumps a tree of children to the debug output.
 
2708
 
 
2709
    This function is useful for debugging, but does nothing if the
 
2710
    library has been compiled in release mode (i.e. without debugging
 
2711
    information).
 
2712
 
 
2713
    \sa dumpObjectInfo()
 
2714
*/
 
2715
 
 
2716
void QObject::dumpObjectTree()
 
2717
{
 
2718
    dumpRecursive(0, this);
 
2719
}
 
2720
 
 
2721
/*!
 
2722
    Dumps information about signal connections, etc. for this object
 
2723
    to the debug output.
 
2724
 
 
2725
    This function is useful for debugging, but does nothing if the
 
2726
    library has been compiled in release mode (i.e. without debugging
 
2727
    information).
 
2728
 
 
2729
    \sa dumpObjectTree()
 
2730
*/
 
2731
 
 
2732
void QObject::dumpObjectInfo()
 
2733
{
 
2734
#if defined(QT_DEBUG)
 
2735
    qDebug("OBJECT %s::%s", metaObject()->className(),
 
2736
           objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data());
 
2737
    //#### signals and slots info missing
 
2738
#endif
 
2739
}
 
2740
 
 
2741
#ifndef QT_NO_USERDATA
 
2742
/*!\internal
 
2743
 */
 
2744
uint QObject::registerUserData()
 
2745
{
 
2746
    static int user_data_registration = 0;
 
2747
    return user_data_registration++;
 
2748
}
 
2749
 
 
2750
/*!\internal
 
2751
 */
 
2752
QObjectUserData::~QObjectUserData()
 
2753
{
 
2754
}
 
2755
 
 
2756
/*!\internal
 
2757
 */
 
2758
void QObject::setUserData(uint id, QObjectUserData* data)
 
2759
{
 
2760
    Q_D(QObject);
 
2761
    d->userData.insert(id, data);
 
2762
}
 
2763
 
 
2764
/*!\internal
 
2765
 */
 
2766
QObjectUserData* QObject::userData(uint id) const
 
2767
{
 
2768
    Q_D(const QObject);
 
2769
    if ((int)id < d->userData.size())
 
2770
        return d->userData.at(id);
 
2771
    return 0;
 
2772
}
 
2773
 
 
2774
#endif // QT_NO_USERDATA
 
2775
 
 
2776
 
 
2777
#ifndef QT_NO_DEBUG_STREAM
 
2778
QDebug operator<<(QDebug dbg, const QObject *o) {
 
2779
#ifndef Q_BROKEN_DEBUG_STREAM
 
2780
    if (!o)
 
2781
        return dbg << "QObject(0x0) ";
 
2782
    dbg.nospace() << o->metaObject()->className() << "(" << (void *)o;
 
2783
    if (!o->objectName().isEmpty())
 
2784
        dbg << ", name = \"" << o->objectName() << '\"';
 
2785
    dbg << ')';
 
2786
    return dbg.space();
 
2787
#else
 
2788
    qWarning("This compiler doesn't support streaming QObject to QDebug");
 
2789
    return dbg;
 
2790
    Q_UNUSED(o);
 
2791
#endif
 
2792
}
 
2793
#endif
 
2794
 
 
2795
/*!
 
2796
  \fn void QObject::insertChild(QObject *object)
 
2797
 
 
2798
  Use setParent() instead, i.e., call object->setParent(this).
 
2799
*/
 
2800
 
 
2801
/*!
 
2802
  \fn void QObject::removeChild(QObject *object)
 
2803
 
 
2804
  Use setParent() instead, i.e., call object->setParent(0).
 
2805
*/
 
2806
 
 
2807
/*!
 
2808
  \fn bool QObject::isA(const char *className) const
 
2809
 
 
2810
  Compare \a className with the object's metaObject()->className() instead.
 
2811
*/
 
2812
 
 
2813
/*!
 
2814
  \fn const char *QObject::className() const
 
2815
 
 
2816
  Use metaObject()->className() instead.
 
2817
*/
 
2818
 
 
2819
/*!
 
2820
  \fn const char *QObject::name() const
 
2821
 
 
2822
  Use objectName() instead.
 
2823
*/
 
2824
 
 
2825
/*!
 
2826
  \fn const char *QObject::name(const char *defaultName) const
 
2827
 
 
2828
  Use objectName() instead.
 
2829
*/
 
2830
 
 
2831
/*!
 
2832
  \fn void QObject::setName(const char *name)
 
2833
 
 
2834
  Use setObjectName() instead.
 
2835
*/
 
2836
 
 
2837
/*!
 
2838
  \fn bool QObject::checkConnectArgs(const char *signal, const
 
2839
  QObject *object, const char *method)
 
2840
 
 
2841
  Use QMetaObject::checkConnectArgs() instead.
 
2842
*/
 
2843
 
 
2844
/*!
 
2845
  \fn QByteArray QObject::normalizeSignalSlot(const char *signalSlot)
 
2846
 
 
2847
  Use QMetaObject::normalizedSignature() instead.
 
2848
*/
 
2849
 
 
2850
/*!
 
2851
  \fn const char *QMetaObject::superClassName() const
 
2852
 
 
2853
  \internal
 
2854
*/
 
2855
 
 
2856
/*!
 
2857
    \macro Q_CLASSINFO(Name, Value)
 
2858
    \relates QObject
 
2859
 
 
2860
    This macro associates extra information to the class, which is
 
2861
    available using QObject::metaObject(). Except for the ActiveQt
 
2862
    extension, Qt doesn't use this information.
 
2863
 
 
2864
    The extra information takes the form of a \a Name string and a \a
 
2865
    Value literal string.
 
2866
 
 
2867
    Example:
 
2868
 
 
2869
    \code
 
2870
        class MyClass : public QObject
 
2871
        {
 
2872
            Q_OBJECT
 
2873
            Q_CLASSINFO("Author", "Pierre Gendron")
 
2874
            Q_CLASSINFO("URL", "http://www.my-organization.qc.ca")
 
2875
 
 
2876
        public:
 
2877
            ...
 
2878
        };
 
2879
    \endcode
 
2880
 
 
2881
    \sa QMetaObject::classInfo()
 
2882
*/
 
2883
 
 
2884
/*!
 
2885
    \macro Q_INTERFACES(...)
 
2886
    \relates QObject
 
2887
 
 
2888
    This macro tells Qt which interfaces the class implements. This
 
2889
    is used when implementing plugins.
 
2890
 
 
2891
    Example:
 
2892
 
 
2893
    \quotefromfile tools/plugandpaintplugins/basictools/basictoolsplugin.h
 
2894
    \skipto class BasicToolsPlugin
 
2895
    \printuntil public:
 
2896
    \dots
 
2897
    \skipto };
 
2898
    \printline };
 
2899
 
 
2900
    See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint
 
2901
    Basic Tools} example for details.
 
2902
 
 
2903
    \sa Q_DECLARE_INTERFACE(), Q_EXPORT_PLUGINS(), {How to Create Qt Plugins}
 
2904
*/
 
2905
 
 
2906
/*!
 
2907
    \macro Q_PROPERTY(...)
 
2908
    \relates QObject
 
2909
 
 
2910
    This macro declares a QObject property. The syntax is:
 
2911
 
 
2912
    \code
 
2913
        Q_PROPERTY(type name
 
2914
                   READ getFunction
 
2915
                   [WRITE setFunction]
 
2916
                   [RESET resetFunction]
 
2917
                   [DESIGNABLE bool] 
 
2918
                   [SCRIPTABLE bool]
 
2919
                   [STORED bool])
 
2920
    \endcode
 
2921
 
 
2922
    For example:
 
2923
 
 
2924
    \code
 
2925
        Q_PROPERTY(QString title READ title WRITE setTitle)
 
2926
    \endcode
 
2927
 
 
2928
    \sa {Qt's Property System}
 
2929
*/
 
2930
 
 
2931
/*!
 
2932
    \macro Q_ENUMS(...)
 
2933
    \relates QObject
 
2934
 
 
2935
    This macro registers one or several enum types to the meta-object
 
2936
    system.
 
2937
 
 
2938
    Example:
 
2939
 
 
2940
    \code
 
2941
        Q_ENUMS(Option AlignmentFlag EditMode TransformationMode)
 
2942
    \endcode
 
2943
 
 
2944
    \sa {Qt's Property System}
 
2945
*/
 
2946
 
 
2947
/*!
 
2948
    \macro Q_FLAGS(...)
 
2949
    \relates QObject
 
2950
 
 
2951
    This macro registers one or several "flags" types to the
 
2952
    meta-object system.
 
2953
 
 
2954
    Example:
 
2955
 
 
2956
    \code
 
2957
        Q_FLAGS(Options Alignment)
 
2958
    \endcode
 
2959
 
 
2960
    \sa {Qt's Property System}
 
2961
*/
 
2962
 
 
2963
#include "moc_qobject.cpp"