Merge branch 'patches/0253-qmake_correct_path_separators', remote branches 'kde-qt...
[qt:kde-qt.git] / src / corelib / kernel / qobject_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial Usage
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file.  Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QOBJECT_P_H
43 #define QOBJECT_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists for the convenience
50 // of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp.  This header
51 // file may change from version to version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "QtCore/qobject.h"
57 #include "QtCore/qpointer.h"
58 #include "QtCore/qcoreevent.h"
59 #include "QtCore/qlist.h"
60 #include "QtCore/qvector.h"
61 #include "QtCore/qreadwritelock.h"
62 #include "QtCore/qvariant.h"
63
64 QT_BEGIN_NAMESPACE
65
66 class QVariant;
67 class QThreadData;
68 class QObjectConnectionListVector;
69 namespace QtSharedPointer { struct ExternalRefCountData; }
70
71 /* mirrored in QtTestLib, DON'T CHANGE without prior warning */
72 struct QSignalSpyCallbackSet
73 {
74     typedef void (*BeginCallback)(QObject *caller, int method_index, void **argv);
75     typedef void (*EndCallback)(QObject *caller, int method_index);
76     BeginCallback signal_begin_callback,
77                     slot_begin_callback;
78     EndCallback signal_end_callback,
79                 slot_end_callback;
80 };
81 void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set);
82
83 extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set;
84
85 // add 0x1000000 to mark it as qt-copy version, with possible modifications
86 // in some Q*Private class
87 enum { QObjectPrivateVersion = QT_VERSION + 0x1000000 };
88
89 class Q_CORE_EXPORT QAbstractDeclarativeData
90 {
91 public:
92     static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
93     static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
94 };
95
96 class Q_CORE_EXPORT QObjectPrivate : public QObjectData
97 {
98     Q_DECLARE_PUBLIC(QObject)
99
100 public:
101     struct ExtraData
102     {
103         ExtraData() {}
104 #ifndef QT_NO_USERDATA
105         QVector<QObjectUserData *> userData;
106 #endif
107         QList<QByteArray> propertyNames;
108         QList<QVariant> propertyValues;
109     };
110
111     struct Connection
112     {
113         QObject *sender;
114         QObject *receiver;
115         int method;
116         uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
117         QBasicAtomicPointer<int> argumentTypes;
118         // The next pointer for the singly-linked ConnectionList
119         Connection *nextConnectionList;
120         //senders linked list
121         Connection *next;
122         Connection **prev;
123         ~Connection();
124     };
125     // ConnectionList is a singly-linked list
126     struct ConnectionList {
127         ConnectionList() : first(0), last(0) {}
128         Connection *first;
129         Connection *last;
130     };
131
132     struct Sender
133     {
134         QObject *sender;
135         int signal;
136         int ref;
137     };
138
139
140     QObjectPrivate(int version = QObjectPrivateVersion);
141     virtual ~QObjectPrivate();
142     void deleteChildren();
143
144     void setParent_helper(QObject *);
145     void moveToThread_helper();
146     void setThreadData_helper(QThreadData *currentData, QThreadData *targetData);
147     void _q_reregisterTimers(void *pointer);
148
149     bool isSender(const QObject *receiver, const char *signal) const;
150     QObjectList receiverList(const char *signal) const;
151     QObjectList senderList() const;
152
153     void addConnection(int signal, Connection *c);
154     void cleanConnectionLists();
155
156 #ifdef QT3_SUPPORT
157     void sendPendingChildInsertedEvents();
158     void removePendingChildInsertedEvents(QObject *child);
159 #endif
160 #if defined(Q_WS_X11)
161     virtual void checkWindowRole();
162 #endif
163
164     static inline Sender *setCurrentSender(QObject *receiver,
165                                     Sender *sender);
166     static inline void resetCurrentSender(QObject *receiver,
167                                    Sender *currentSender,
168                                    Sender *previousSender);
169     static int *setDeleteWatch(QObjectPrivate *d, int *newWatch);
170     static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch);
171     static void clearGuards(QObject *);
172
173     static QObjectPrivate *get(QObject *o) {
174         return o->d_func();
175     }
176
177     int signalIndex(const char *signalName) const;
178     inline bool isSignalConnected(uint signalIdx) const;
179
180 public:
181     QString objectName;
182     ExtraData *extraData;    // extra data set by the user
183     QThreadData *threadData; // id of the thread that owns the object
184
185     QObjectConnectionListVector *connectionLists;
186
187     Connection *senders;     // linked list of connections connected to this object
188     Sender *currentSender;   // object currently activating the object
189     mutable quint32 connectedSignals[2];
190
191 #ifdef QT3_SUPPORT
192     QList<QObject *> pendingChildInsertedEvents;
193 #else
194     // preserve binary compatibility with code compiled without Qt 3 support
195     // keeping the binary layout stable helps the Qt Creator debugger
196     void *unused;
197 #endif
198
199     QList<QPointer<QObject> > eventFilters;
200     union {
201         QObject *currentChildBeingDeleted;
202         QAbstractDeclarativeData *declarativeData; //extra data used by the declarative module
203     };
204
205     // these objects are all used to indicate that a QObject was deleted
206     // plus QPointer, which keeps a separate list
207     QAtomicPointer<QtSharedPointer::ExternalRefCountData> sharedRefcount;
208     int *deleteWatch;
209 };
210
211
212 /*! \internal
213
214   Returns true if the signal with index \a signal_index from object \a sender is connected.
215   Signals with indices above a certain range are always considered connected (see connectedSignals
216   in QObjectPrivate). If a signal spy is installed, all signals are considered connected.
217
218   \a signal_index must be the index returned by QObjectPrivate::signalIndex;
219 */
220 inline bool QObjectPrivate::isSignalConnected(uint signal_index) const
221 {
222     return signal_index >= sizeof(connectedSignals) * 8
223         || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
224         || qt_signal_spy_callback_set.signal_begin_callback
225         || qt_signal_spy_callback_set.signal_end_callback);
226 }
227
228 inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver,
229                                                          Sender *sender)
230 {
231     Sender *previousSender = receiver->d_func()->currentSender;
232     receiver->d_func()->currentSender = sender;
233     return previousSender;
234 }
235
236 inline void QObjectPrivate::resetCurrentSender(QObject *receiver,
237                                         Sender *currentSender,
238                                         Sender *previousSender)
239 {
240     // ref is set to zero when this object is deleted during the metacall
241     if (currentSender->ref == 1)
242         receiver->d_func()->currentSender = previousSender;
243     // if we've recursed, we need to tell the caller about the objects deletion
244     if (previousSender)
245         previousSender->ref = currentSender->ref;
246 }
247
248
249 Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
250 Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE);
251
252 class QSemaphore;
253 class Q_CORE_EXPORT QMetaCallEvent : public QEvent
254 {
255 public:
256     QMetaCallEvent(int id, const QObject *sender, int signalId,
257                    int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
258     ~QMetaCallEvent();
259
260     inline int id() const { return id_; }
261     inline const QObject *sender() const { return sender_; }
262     inline int signalId() const { return signalId_; }
263     inline void **args() const { return args_; }
264
265     virtual int placeMetaCall(QObject *object);
266
267 private:
268     int id_;
269     const QObject *sender_;
270     int signalId_;
271     int nargs_;
272     int *types_;
273     void **args_;
274     QSemaphore *semaphore_;
275 };
276
277 class QBoolBlocker
278 {
279 public:
280     inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
281     inline ~QBoolBlocker(){block = reset; }
282 private:
283     bool &block;
284     bool reset;
285 };
286
287 void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o);
288
289
290 struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QMetaObject
291 {
292     virtual ~QAbstractDynamicMetaObject() {}
293     virtual int metaCall(QMetaObject::Call, int _id, void **) { return _id; }
294     virtual int createProperty(const char *, const char *) { return -1; }
295 };
296
297 QT_END_NAMESPACE
298
299 #endif // QOBJECT_P_H