Line data Source code
1 : /****************************************************************************
2 : **
3 : ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 : ** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
5 : ** Contact: http://www.qt-project.org/legal
6 : **
7 : ** This file is part of the QtCore module of the Qt Toolkit.
8 : **
9 : ** $QT_BEGIN_LICENSE:LGPL$
10 : ** Commercial License Usage
11 : ** Licensees holding valid commercial Qt licenses may use this file in
12 : ** accordance with the commercial license agreement provided with the
13 : ** Software or, alternatively, in accordance with the terms contained in
14 : ** a written agreement between you and Digia. For licensing terms and
15 : ** conditions see http://qt.digia.com/licensing. For further information
16 : ** use the contact form at http://qt.digia.com/contact-us.
17 : **
18 : ** GNU Lesser General Public License Usage
19 : ** Alternatively, this file may be used under the terms of the GNU Lesser
20 : ** General Public License version 2.1 as published by the Free Software
21 : ** Foundation and appearing in the file LICENSE.LGPL included in the
22 : ** packaging of this file. Please review the following information to
23 : ** ensure the GNU Lesser General Public License version 2.1 requirements
24 : ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 : **
26 : ** In addition, as a special exception, Digia gives you certain additional
27 : ** rights. These rights are described in the Digia Qt LGPL Exception
28 : ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 : **
30 : ** GNU General Public License Usage
31 : ** Alternatively, this file may be used under the terms of the GNU
32 : ** General Public License version 3.0 as published by the Free Software
33 : ** Foundation and appearing in the file LICENSE.GPL included in the
34 : ** packaging of this file. Please review the following information to
35 : ** ensure the GNU General Public License version 3.0 requirements will be
36 : ** met: http://www.gnu.org/copyleft/gpl.html.
37 : **
38 : **
39 : ** $QT_END_LICENSE$
40 : **
41 : ****************************************************************************/
42 :
43 : #ifndef QOBJECT_H
44 : #define QOBJECT_H
45 :
46 : #ifndef QT_NO_QOBJECT
47 :
48 : #include <QtCore/qobjectdefs.h>
49 : #include <QtCore/qstring.h>
50 : #include <QtCore/qbytearray.h>
51 : #include <QtCore/qlist.h>
52 : #ifdef QT_INCLUDE_COMPAT
53 : #include <QtCore/qcoreevent.h>
54 : #endif
55 : #include <QtCore/qscopedpointer.h>
56 : #include <QtCore/qmetatype.h>
57 :
58 : #include <QtCore/qobject_impl.h>
59 :
60 : QT_BEGIN_NAMESPACE
61 :
62 :
63 : class QEvent;
64 : class QTimerEvent;
65 : class QChildEvent;
66 : struct QMetaObject;
67 : class QVariant;
68 : class QObjectPrivate;
69 : class QObject;
70 : class QThread;
71 : class QWidget;
72 : #ifndef QT_NO_REGEXP
73 : class QRegExp;
74 : #endif
75 : #ifndef QT_NO_REGULAREXPRESSION
76 : class QRegularExpression;
77 : #endif
78 : #ifndef QT_NO_USERDATA
79 : class QObjectUserData;
80 : #endif
81 : struct QDynamicMetaObjectData;
82 :
83 : typedef QList<QObject*> QObjectList;
84 :
85 : Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name,
86 : const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
87 : Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
88 : const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
89 : Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
90 : const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
91 : Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
92 :
93 : class Q_CORE_EXPORT QObjectData {
94 : public:
95 : virtual ~QObjectData() = 0;
96 : QObject *q_ptr;
97 : QObject *parent;
98 : QObjectList children;
99 :
100 : uint isWidget : 1;
101 : uint blockSig : 1;
102 : uint wasDeleted : 1;
103 : uint isDeletingChildren : 1;
104 : uint sendChildEvents : 1;
105 : uint receiveChildEvents : 1;
106 : uint isWindow : 1; //for QWindow
107 : uint unused : 25;
108 : int postedEvents;
109 : QDynamicMetaObjectData *metaObject;
110 : QMetaObject *dynamicMetaObject() const;
111 : };
112 :
113 :
114 : class Q_CORE_EXPORT QObject
115 : {
116 : Q_OBJECT
117 : Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
118 : Q_DECLARE_PRIVATE(QObject)
119 :
120 : public:
121 : Q_INVOKABLE explicit QObject(QObject *parent=0);
122 : virtual ~QObject();
123 :
124 : virtual bool event(QEvent *);
125 : virtual bool eventFilter(QObject *, QEvent *);
126 :
127 : #ifdef Q_QDOC
128 : static QString tr(const char *sourceText, const char *comment = 0, int n = -1);
129 : static QString trUtf8(const char *sourceText, const char *comment = 0, int n = -1);
130 : virtual const QMetaObject *metaObject() const;
131 : static const QMetaObject staticMetaObject;
132 : #endif
133 : #ifdef QT_NO_TRANSLATION
134 : static QString tr(const char *sourceText, const char * = 0, int = -1)
135 : { return QString::fromUtf8(sourceText); }
136 : #if QT_DEPRECATED_SINCE(5, 0)
137 : QT_DEPRECATED static QString trUtf8(const char *sourceText, const char * = 0, int = -1)
138 : { return QString::fromUtf8(sourceText); }
139 : #endif
140 : #endif //QT_NO_TRANSLATION
141 :
142 : QString objectName() const;
143 : void setObjectName(const QString &name);
144 :
145 : inline bool isWidgetType() const { return d_ptr->isWidget; }
146 : inline bool isWindowType() const { return d_ptr->isWindow; }
147 :
148 : inline bool signalsBlocked() const { return d_ptr->blockSig; }
149 : bool blockSignals(bool b);
150 :
151 : QThread *thread() const;
152 : void moveToThread(QThread *thread);
153 :
154 : int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
155 : void killTimer(int id);
156 :
157 : template<typename T>
158 : inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
159 : { return static_cast<T>(qt_qFindChild_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject, options)); }
160 :
161 : template<typename T>
162 : inline QList<T> findChildren(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
163 : {
164 : QList<T> list;
165 : qt_qFindChildren_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject,
166 : reinterpret_cast<QList<void *> *>(&list), options);
167 : return list;
168 : }
169 :
170 : #ifndef QT_NO_REGEXP
171 : template<typename T>
172 : inline QList<T> findChildren(const QRegExp &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
173 : {
174 : QList<T> list;
175 : qt_qFindChildren_helper(this, re, reinterpret_cast<T>(0)->staticMetaObject,
176 : reinterpret_cast<QList<void *> *>(&list), options);
177 : return list;
178 : }
179 : #endif
180 :
181 : #ifndef QT_NO_REGULAREXPRESSION
182 : template<typename T>
183 : inline QList<T> findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
184 : {
185 : QList<T> list;
186 : qt_qFindChildren_helper(this, re, reinterpret_cast<T>(0)->staticMetaObject,
187 : reinterpret_cast<QList<void *> *>(&list), options);
188 : return list;
189 : }
190 : #endif
191 :
192 : inline const QObjectList &children() const { return d_ptr->children; }
193 :
194 : void setParent(QObject *);
195 : void installEventFilter(QObject *);
196 : void removeEventFilter(QObject *);
197 :
198 : static QMetaObject::Connection connect(const QObject *sender, const char *signal,
199 : const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);
200 :
201 : static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
202 : const QObject *receiver, const QMetaMethod &method,
203 : Qt::ConnectionType type = Qt::AutoConnection);
204 :
205 : inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
206 : const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;
207 :
208 : #ifdef Q_QDOC
209 : static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
210 : static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor);
211 : static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);
212 : #else
213 : //Connect a signal to a pointer to qobject member function
214 : template <typename Func1, typename Func2>
215 34 : static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
216 : const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
217 : Qt::ConnectionType type = Qt::AutoConnection)
218 : {
219 : typedef QtPrivate::FunctionPointer<Func1> SignalType;
220 : typedef QtPrivate::FunctionPointer<Func2> SlotType;
221 :
222 : Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
223 : "No Q_OBJECT in the class with the signal");
224 :
225 : //compilation error if the arguments does not match.
226 : Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
227 : "The slot requires more arguments than the signal provides.");
228 : Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
229 : "Signal and slot arguments are not compatible.");
230 : Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
231 : "Return type of the slot is not compatible with the return type of the signal.");
232 :
233 34 : const int *types = 0;
234 34 : if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
235 0 : types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
236 :
237 : return connectImpl(sender, reinterpret_cast<void **>(&signal),
238 : receiver, reinterpret_cast<void **>(&slot),
239 : new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
240 : typename SignalType::ReturnType>(slot),
241 34 : type, types, &SignalType::Object::staticMetaObject);
242 : }
243 :
244 : //connect to a function pointer (not a member)
245 : template <typename Func1, typename Func2>
246 : static inline typename QtPrivate::QEnableIf<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0, QMetaObject::Connection>::Type
247 : connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
248 : {
249 : return connect(sender, signal, sender, slot, Qt::DirectConnection);
250 : }
251 :
252 : //connect to a function pointer (not a member)
253 : template <typename Func1, typename Func2>
254 : static inline typename QtPrivate::QEnableIf<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0 &&
255 : !QtPrivate::FunctionPointer<Func2>::IsPointerToMemberFunction, QMetaObject::Connection>::Type
256 : connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
257 : Qt::ConnectionType type = Qt::AutoConnection)
258 : {
259 : typedef QtPrivate::FunctionPointer<Func1> SignalType;
260 : typedef QtPrivate::FunctionPointer<Func2> SlotType;
261 :
262 : Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
263 : "No Q_OBJECT in the class with the signal");
264 :
265 : //compilation error if the arguments does not match.
266 : Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
267 : "The slot requires more arguments than the signal provides.");
268 : Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
269 : "Signal and slot arguments are not compatible.");
270 : Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
271 : "Return type of the slot is not compatible with the return type of the signal.");
272 :
273 : const int *types = 0;
274 : if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
275 : types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
276 :
277 : return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
278 : new QtPrivate::QStaticSlotObject<Func2,
279 : typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
280 : typename SignalType::ReturnType>(slot),
281 : type, types, &SignalType::Object::staticMetaObject);
282 : }
283 :
284 : //connect to a functor
285 : template <typename Func1, typename Func2>
286 : static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
287 : connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
288 : {
289 : return connect(sender, signal, sender, slot, Qt::DirectConnection);
290 : }
291 :
292 : //connect to a functor, with a "context" object defining in which event loop is going to be executed
293 : template <typename Func1, typename Func2>
294 : static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
295 7 : connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
296 : Qt::ConnectionType type = Qt::AutoConnection)
297 : {
298 : #if defined (Q_COMPILER_DECLTYPE) && defined (Q_COMPILER_VARIADIC_TEMPLATES)
299 : typedef QtPrivate::FunctionPointer<Func1> SignalType;
300 7 : const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
301 :
302 : Q_STATIC_ASSERT_X((FunctorArgumentCount >= 0),
303 : "Signal and slot arguments are not compatible.");
304 7 : const int SlotArgumentCount = (FunctorArgumentCount >= 0) ? FunctorArgumentCount : 0;
305 : typedef typename QtPrivate::FunctorReturnType<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value>::Value SlotReturnType;
306 : #else
307 : // Without variadic template, we don't detect the best overload of operator(). We just
308 : // assume there is only one simple operator() and connect to &Func2::operator()
309 :
310 : /* If you get an error such as:
311 : couldn't deduce template parameter 'Func2Operator'
312 : or
313 : cannot resolve address of overloaded function
314 : It means the functor does not have a single operator().
315 : Functors with overloaded or templated operator() are only supported if the compiler supports
316 : C++11 variadic templates
317 : */
318 : #ifndef Q_COMPILER_DECLTYPE //Workaround the lack of decltype using another function as indirection
319 : return connect_functor(sender, signal, context, slot, &Func2::operator(), type); }
320 : template <typename Func1, typename Func2, typename Func2Operator>
321 : static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, const QObject *context,
322 : Func2 slot, Func2Operator, Qt::ConnectionType type) {
323 : typedef QtPrivate::FunctionPointer<Func2Operator> SlotType ;
324 : #else
325 : typedef QtPrivate::FunctionPointer<decltype(&Func2::operator())> SlotType ;
326 : #endif
327 : typedef QtPrivate::FunctionPointer<Func1> SignalType;
328 : typedef typename SlotType::ReturnType SlotReturnType;
329 : const int SlotArgumentCount = SlotType::ArgumentCount;
330 :
331 : Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= SlotArgumentCount,
332 : "The slot requires more arguments than the signal provides.");
333 : Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
334 : "Signal and slot arguments are not compatible.");
335 : #endif
336 :
337 : Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
338 : "Return type of the slot is not compatible with the return type of the signal.");
339 :
340 : Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
341 : "No Q_OBJECT in the class with the signal");
342 :
343 7 : const int *types = 0;
344 7 : if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
345 0 : types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
346 :
347 : return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
348 : new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
349 : typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
350 : typename SignalType::ReturnType>(slot),
351 7 : type, types, &SignalType::Object::staticMetaObject);
352 : }
353 : #endif //Q_QDOC
354 :
355 : static bool disconnect(const QObject *sender, const char *signal,
356 : const QObject *receiver, const char *member);
357 : static bool disconnect(const QObject *sender, const QMetaMethod &signal,
358 : const QObject *receiver, const QMetaMethod &member);
359 : inline bool disconnect(const char *signal = 0,
360 : const QObject *receiver = 0, const char *member = 0) const
361 : { return disconnect(this, signal, receiver, member); }
362 : inline bool disconnect(const QObject *receiver, const char *member = 0) const
363 : { return disconnect(this, 0, receiver, member); }
364 : static bool disconnect(const QMetaObject::Connection &);
365 :
366 : #ifdef Q_QDOC
367 : static bool disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method);
368 : #else
369 : template <typename Func1, typename Func2>
370 : static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
371 : const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot)
372 : {
373 : typedef QtPrivate::FunctionPointer<Func1> SignalType;
374 : typedef QtPrivate::FunctionPointer<Func2> SlotType;
375 :
376 : Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
377 : "No Q_OBJECT in the class with the signal");
378 :
379 : //compilation error if the arguments does not match.
380 : Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
381 : "Signal and slot arguments are not compatible.");
382 :
383 : return disconnectImpl(sender, reinterpret_cast<void **>(&signal), receiver, reinterpret_cast<void **>(&slot),
384 : &SignalType::Object::staticMetaObject);
385 : }
386 : template <typename Func1>
387 : static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
388 : const QObject *receiver, void **zero)
389 : {
390 : // This is the overload for when one wish to disconnect a signal from any slot. (slot=0)
391 : // Since the function template parameter cannot be deduced from '0', we use a
392 : // dummy void ** parameter that must be equal to 0
393 : Q_ASSERT(!zero);
394 : typedef QtPrivate::FunctionPointer<Func1> SignalType;
395 : return disconnectImpl(sender, reinterpret_cast<void **>(&signal), receiver, zero,
396 : &SignalType::Object::staticMetaObject);
397 : }
398 : #endif //Q_QDOC
399 :
400 :
401 : void dumpObjectTree();
402 : void dumpObjectInfo();
403 :
404 : #ifndef QT_NO_PROPERTIES
405 : bool setProperty(const char *name, const QVariant &value);
406 : QVariant property(const char *name) const;
407 : QList<QByteArray> dynamicPropertyNames() const;
408 : #endif // QT_NO_PROPERTIES
409 :
410 : #ifndef QT_NO_USERDATA
411 : static uint registerUserData();
412 : void setUserData(uint id, QObjectUserData* data);
413 : QObjectUserData* userData(uint id) const;
414 : #endif // QT_NO_USERDATA
415 :
416 : Q_SIGNALS:
417 : void destroyed(QObject * = 0);
418 : void objectNameChanged(const QString &objectName
419 : #if !defined(Q_QDOC)
420 : , QPrivateSignal
421 : #endif
422 : );
423 :
424 : public:
425 : inline QObject *parent() const { return d_ptr->parent; }
426 :
427 : inline bool inherits(const char *classname) const
428 : { return const_cast<QObject *>(this)->qt_metacast(classname) != 0; }
429 :
430 : public Q_SLOTS:
431 : void deleteLater();
432 :
433 : protected:
434 : QObject *sender() const;
435 : int senderSignalIndex() const;
436 : int receivers(const char* signal) const;
437 : bool isSignalConnected(const QMetaMethod &signal) const;
438 :
439 : virtual void timerEvent(QTimerEvent *);
440 : virtual void childEvent(QChildEvent *);
441 : virtual void customEvent(QEvent *);
442 :
443 : virtual void connectNotify(const QMetaMethod &signal);
444 : virtual void disconnectNotify(const QMetaMethod &signal);
445 :
446 : protected:
447 : QObject(QObjectPrivate &dd, QObject *parent = 0);
448 :
449 : protected:
450 : QScopedPointer<QObjectData> d_ptr;
451 :
452 : static const QMetaObject staticQtMetaObject;
453 :
454 : friend struct QMetaObject;
455 : friend struct QMetaObjectPrivate;
456 : friend class QMetaCallEvent;
457 : friend class QApplication;
458 : friend class QApplicationPrivate;
459 : friend class QCoreApplication;
460 : friend class QCoreApplicationPrivate;
461 : friend class QWidget;
462 : friend class QThreadData;
463 :
464 : private:
465 : Q_DISABLE_COPY(QObject)
466 : Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *))
467 :
468 : private:
469 : static QMetaObject::Connection connectImpl(const QObject *sender, void **signal,
470 : const QObject *receiver, void **slotPtr,
471 : QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type,
472 : const int *types, const QMetaObject *senderMetaObject);
473 :
474 : static bool disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot,
475 : const QMetaObject *senderMetaObject);
476 :
477 : };
478 :
479 0 : inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,
480 : const char *amember, Qt::ConnectionType atype) const
481 0 : { return connect(asender, asignal, this, amember, atype); }
482 :
483 : #ifndef QT_NO_USERDATA
484 : class Q_CORE_EXPORT QObjectUserData {
485 : public:
486 : virtual ~QObjectUserData();
487 : };
488 : #endif
489 :
490 : #ifdef Q_QDOC
491 : T qFindChild(const QObject *o, const QString &name = QString());
492 : QList<T> qFindChildren(const QObject *oobj, const QString &name = QString());
493 : QList<T> qFindChildren(const QObject *o, const QRegExp &re);
494 : #endif
495 : #if QT_DEPRECATED_SINCE(5, 0)
496 : template<typename T>
497 : inline QT_DEPRECATED T qFindChild(const QObject *o, const QString &name = QString())
498 : { return o->findChild<T>(name); }
499 :
500 : template<typename T>
501 : inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QString &name = QString())
502 : {
503 : return o->findChildren<T>(name);
504 : }
505 :
506 : #ifndef QT_NO_REGEXP
507 : template<typename T>
508 : inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QRegExp &re)
509 : {
510 : return o->findChildren<T>(re);
511 : }
512 : #endif
513 :
514 : #endif //QT_DEPRECATED
515 :
516 : template <class T>
517 126 : inline T qobject_cast(QObject *object)
518 : {
519 : typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
520 : Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
521 : "qobject_cast requires the type to have a Q_OBJECT macro");
522 126 : return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
523 : }
524 :
525 : template <class T>
526 : inline T qobject_cast(const QObject *object)
527 : {
528 : typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
529 : Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
530 : "qobject_cast requires the type to have a Q_OBJECT macro");
531 : return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
532 : }
533 :
534 :
535 : template <class T> inline const char * qobject_interface_iid()
536 : { return 0; }
537 :
538 : #ifndef Q_MOC_RUN
539 : # define Q_DECLARE_INTERFACE(IFace, IId) \
540 : template <> inline const char *qobject_interface_iid<IFace *>() \
541 : { return IId; } \
542 : template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
543 : { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \
544 : template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \
545 : { return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : 0)); }
546 : #endif // Q_MOC_RUN
547 :
548 : #ifndef QT_NO_DEBUG_STREAM
549 : Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *);
550 : #endif
551 :
552 : class QSignalBlocker
553 : {
554 : public:
555 : inline explicit QSignalBlocker(QObject *o);
556 : inline explicit QSignalBlocker(QObject &o);
557 : inline ~QSignalBlocker();
558 :
559 : #ifdef Q_COMPILER_RVALUE_REFS
560 : inline QSignalBlocker(QSignalBlocker &&other);
561 : inline QSignalBlocker &operator=(QSignalBlocker &&other);
562 : #endif
563 :
564 : inline void reblock();
565 : inline void unblock();
566 : private:
567 : Q_DISABLE_COPY(QSignalBlocker)
568 : QObject * m_o;
569 : bool m_blocked;
570 : bool m_inhibited;
571 : };
572 :
573 : QSignalBlocker::QSignalBlocker(QObject *o)
574 : : m_o(o),
575 : m_blocked(o && o->blockSignals(true)),
576 : m_inhibited(false)
577 : {}
578 :
579 : QSignalBlocker::QSignalBlocker(QObject &o)
580 : : m_o(&o),
581 : m_blocked(o.blockSignals(true)),
582 : m_inhibited(false)
583 : {}
584 :
585 : #ifdef Q_COMPILER_RVALUE_REFS
586 : QSignalBlocker::QSignalBlocker(QSignalBlocker &&other)
587 : : m_o(other.m_o),
588 : m_blocked(other.m_blocked),
589 : m_inhibited(other.m_inhibited)
590 : {
591 : other.m_o = 0;
592 : }
593 :
594 : QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other)
595 : {
596 : if (this != &other) {
597 : // if both *this and other block the same object's signals:
598 : // unblock *this iff our dtor would unblock, but other's wouldn't
599 : if (m_o != other.m_o || (!m_inhibited && other.m_inhibited))
600 : unblock();
601 : m_o = other.m_o;
602 : m_blocked = other.m_blocked;
603 : m_inhibited = other.m_inhibited;
604 : // disable other:
605 : other.m_o = 0;
606 : }
607 : return *this;
608 : }
609 : #endif
610 :
611 : QSignalBlocker::~QSignalBlocker()
612 : {
613 : if (m_o && !m_inhibited)
614 : m_o->blockSignals(m_blocked);
615 : }
616 :
617 : void QSignalBlocker::reblock()
618 : {
619 : if (m_o) m_o->blockSignals(true);
620 : m_inhibited = false;
621 : }
622 :
623 : void QSignalBlocker::unblock()
624 : {
625 : if (m_o) m_o->blockSignals(m_blocked);
626 : m_inhibited = true;
627 : }
628 :
629 : namespace QtPrivate {
630 : inline QObject & deref_for_methodcall(QObject &o) { return o; }
631 : inline QObject & deref_for_methodcall(QObject *o) { return *o; }
632 : }
633 : #define Q_SET_OBJECT_NAME(obj) QT_PREPEND_NAMESPACE(QtPrivate)::deref_for_methodcall(obj).setObjectName(QLatin1String(#obj))
634 :
635 : QT_END_NAMESPACE
636 :
637 : #endif
638 :
639 : #endif // QOBJECT_H
|