1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QQMLGLOBAL_H |
5 | #define QQMLGLOBAL_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <private/qmetaobject_p.h> |
19 | #include <private/qtqmlglobal_p.h> |
20 | #include <private/qqmlmetaobject_p.h> |
21 | |
22 | #include <QtQml/qqml.h> |
23 | #include <QtCore/qobject.h> |
24 | |
25 | QT_BEGIN_NAMESPACE |
26 | |
27 | inline bool qmlConvertBoolConfigOption(const char *v) |
28 | { |
29 | return v != nullptr && qstrcmp(str1: v, str2: "0" ) != 0 && qstrcmp(str1: v, str2: "false" ) != 0; |
30 | } |
31 | |
32 | template<typename T, T(*Convert)(const char *)> |
33 | T qmlGetConfigOption(const char *var) |
34 | { |
35 | if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) |
36 | return Convert(qgetenv(varName: var)); |
37 | return Convert(nullptr); |
38 | } |
39 | |
40 | #define DEFINE_BOOL_CONFIG_OPTION(name, var) \ |
41 | static bool name() \ |
42 | { \ |
43 | static const bool result = qmlGetConfigOption<bool, qmlConvertBoolConfigOption>(#var); \ |
44 | return result; \ |
45 | } |
46 | |
47 | /*! |
48 | Connect \a Signal of \a Sender to \a Method of \a Receiver. \a Signal must be |
49 | of type \a SenderType and \a Receiver of type \a ReceiverType. |
50 | |
51 | Unlike QObject::connect(), this method caches the lookup of the signal and method |
52 | indexes. It also does not require lazy QMetaObjects to be built so should be |
53 | preferred in all QML code that might interact with QML built objects. |
54 | |
55 | \code |
56 | QQuickTextControl *control; |
57 | QQuickTextEdit *textEdit; |
58 | qmlobject_connect(control, QQuickTextControl, SIGNAL(updateRequest(QRectF)), |
59 | textEdit, QQuickTextEdit, SLOT(updateDocument())); |
60 | \endcode |
61 | */ |
62 | #define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method) \ |
63 | do { \ |
64 | SenderType *sender = (Sender); \ |
65 | ReceiverType *receiver = (Receiver); \ |
66 | const char *signal = (Signal); \ |
67 | const char *method = (Method); \ |
68 | static int signalIdx = -1; \ |
69 | static int methodIdx = -1; \ |
70 | if (signalIdx < 0) { \ |
71 | Q_ASSERT((int(*signal) - '0') == QSIGNAL_CODE); \ |
72 | signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \ |
73 | } \ |
74 | if (methodIdx < 0) { \ |
75 | int code = (int(*method) - '0'); \ |
76 | Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \ |
77 | if (code == QSLOT_CODE) \ |
78 | methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \ |
79 | else \ |
80 | methodIdx = ReceiverType::staticMetaObject.indexOfSignal(method+1); \ |
81 | } \ |
82 | Q_ASSERT(signalIdx != -1 && methodIdx != -1); \ |
83 | QMetaObject::connect(sender, signalIdx, receiver, methodIdx, Qt::DirectConnection); \ |
84 | } while (0) |
85 | |
86 | /*! |
87 | Disconnect \a Signal of \a Sender from \a Method of \a Receiver. \a Signal must be |
88 | of type \a SenderType and \a Receiver of type \a ReceiverType. |
89 | |
90 | Unlike QObject::disconnect(), this method caches the lookup of the signal and method |
91 | indexes. It also does not require lazy QMetaObjects to be built so should be |
92 | preferred in all QML code that might interact with QML built objects. |
93 | |
94 | \code |
95 | QQuickTextControl *control; |
96 | QQuickTextEdit *textEdit; |
97 | qmlobject_disconnect(control, QQuickTextControl, SIGNAL(updateRequest(QRectF)), |
98 | textEdit, QQuickTextEdit, SLOT(updateDocument())); |
99 | \endcode |
100 | */ |
101 | #define qmlobject_disconnect(Sender, SenderType, Signal, Receiver, ReceiverType, Method) \ |
102 | do { \ |
103 | SenderType *sender = (Sender); \ |
104 | ReceiverType *receiver = (Receiver); \ |
105 | const char *signal = (Signal); \ |
106 | const char *method = (Method); \ |
107 | static int signalIdx = -1; \ |
108 | static int methodIdx = -1; \ |
109 | if (signalIdx < 0) { \ |
110 | Q_ASSERT((int(*signal) - '0') == QSIGNAL_CODE); \ |
111 | signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \ |
112 | } \ |
113 | if (methodIdx < 0) { \ |
114 | int code = (int(*method) - '0'); \ |
115 | Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \ |
116 | if (code == QSLOT_CODE) \ |
117 | methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \ |
118 | else \ |
119 | methodIdx = ReceiverType::staticMetaObject.indexOfSignal(method+1); \ |
120 | } \ |
121 | Q_ASSERT(signalIdx != -1 && methodIdx != -1); \ |
122 | QMetaObject::disconnect(sender, signalIdx, receiver, methodIdx); \ |
123 | } while (0) |
124 | |
125 | Q_QML_PRIVATE_EXPORT bool qmlobject_can_cast(QObject *object, const QMetaObject *mo); |
126 | |
127 | /*! |
128 | This method is identical to qobject_cast<T>() except that it does not require lazy |
129 | QMetaObjects to be built, so should be preferred in all QML code that might interact |
130 | with QML built objects. |
131 | |
132 | \code |
133 | QObject *object; |
134 | if (QQuickTextEdit *textEdit = qmlobject_cast<QQuickTextEdit *>(object)) { |
135 | // ...Do something... |
136 | } |
137 | \endcode |
138 | */ |
139 | template<class T> |
140 | T qmlobject_cast(QObject *object) |
141 | { |
142 | if (!object) |
143 | return nullptr; |
144 | if (qmlobject_can_cast(object, &(std::remove_pointer_t<T>::staticMetaObject))) |
145 | return static_cast<T>(object); |
146 | else |
147 | return nullptr; |
148 | } |
149 | |
150 | class QQuickItem; |
151 | template<> |
152 | inline QQuickItem *qmlobject_cast<QQuickItem *>(QObject *object) |
153 | { |
154 | if (!object || !object->isQuickItemType()) |
155 | return nullptr; |
156 | // QQuickItem is incomplete here -> can't use static_cast |
157 | // but we don't need any pointer adjustment, so reinterpret is safe |
158 | return reinterpret_cast<QQuickItem *>(object); |
159 | } |
160 | |
161 | #define IS_SIGNAL_CONNECTED(Sender, SenderType, Name, Arguments) \ |
162 | do { \ |
163 | QObject *sender = (Sender); \ |
164 | void (SenderType::*signal)Arguments = &SenderType::Name; \ |
165 | static QMetaMethod method = QMetaMethod::fromSignal(signal); \ |
166 | static int signalIdx = QMetaObjectPrivate::signalIndex(method); \ |
167 | return QObjectPrivate::get(sender)->isSignalConnected(signalIdx); \ |
168 | } while (0) |
169 | |
170 | /*! |
171 | Returns true if the case of \a fileName is equivalent to the file case of |
172 | \a fileName on disk, and false otherwise. |
173 | |
174 | This is used to ensure that the behavior of QML on a case-insensitive file |
175 | system is the same as on a case-sensitive file system. This function |
176 | performs a "best effort" attempt to determine the real case of the file. |
177 | It may have false positives (say the case is correct when it isn't), but it |
178 | should never have a false negative (say the case is incorrect when it is |
179 | correct). |
180 | |
181 | Length specifies specifies the number of characters to be checked from |
182 | behind. That is, if a file name results from a relative path specification |
183 | like "foo/bar.qml" and is made absolute, the original length (11) should |
184 | be passed indicating that only the last part of the relative path should |
185 | be checked. |
186 | |
187 | */ |
188 | bool QQml_isFileCaseCorrect(const QString &fileName, int length = -1); |
189 | |
190 | /*! |
191 | Makes the \a object a child of \a parent. Note that when using this method, |
192 | neither \a parent nor the object's previous parent (if it had one) will |
193 | receive ChildRemoved or ChildAdded events. |
194 | */ |
195 | inline void QQml_setParent_noEvent(QObject *object, QObject *parent) |
196 | { |
197 | QObjectPrivate *d_ptr = QObjectPrivate::get(o: object); |
198 | bool sce = d_ptr->sendChildEvents; |
199 | d_ptr->sendChildEvents = false; |
200 | object->setParent(parent); |
201 | d_ptr->sendChildEvents = sce; |
202 | } |
203 | |
204 | class QQmlValueTypeProvider |
205 | { |
206 | public: |
207 | static bool createValueType(QMetaType targetMetaType, void *target, const QV4::Value &source); |
208 | static bool createValueType( |
209 | QMetaType targetMetaType, void *target, QMetaType sourceMetaType, void *source); |
210 | |
211 | static QVariant constructValueType( |
212 | QMetaType targetMetaType, const QMetaObject *targetMetaObject, |
213 | int ctorIndex, void *ctorArg); |
214 | |
215 | static QVariant createValueType(const QJSValue &, QMetaType); |
216 | static QVariant createValueType(const QString &, QMetaType); |
217 | static QVariant createValueType(const QV4::Value &, QMetaType); |
218 | static QVariant createValueType(const QVariant &, QMetaType); |
219 | }; |
220 | |
221 | class Q_QML_PRIVATE_EXPORT QQmlColorProvider |
222 | { |
223 | public: |
224 | virtual ~QQmlColorProvider(); |
225 | virtual QVariant colorFromString(const QString &, bool *); |
226 | virtual unsigned rgbaFromString(const QString &, bool *); |
227 | |
228 | virtual QVariant fromRgbF(double, double, double, double); |
229 | virtual QVariant fromHslF(double, double, double, double); |
230 | virtual QVariant fromHsvF(double, double, double, double); |
231 | virtual QVariant lighter(const QVariant &, qreal); |
232 | virtual QVariant darker(const QVariant &, qreal); |
233 | virtual QVariant alpha(const QVariant &, qreal); |
234 | virtual QVariant tint(const QVariant &, const QVariant &); |
235 | }; |
236 | |
237 | Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_setColorProvider(QQmlColorProvider *); |
238 | Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_colorProvider(); |
239 | |
240 | class QQmlApplication; |
241 | class Q_QML_PRIVATE_EXPORT QQmlGuiProvider |
242 | { |
243 | public: |
244 | virtual ~QQmlGuiProvider(); |
245 | virtual QQmlApplication *application(QObject *parent); |
246 | virtual QObject *inputMethod(); |
247 | virtual QObject *styleHints(); |
248 | virtual QStringList fontFamilies(); |
249 | virtual bool openUrlExternally(const QUrl &); |
250 | virtual QString pluginName() const; |
251 | }; |
252 | |
253 | Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *); |
254 | Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(); |
255 | |
256 | class QQmlApplicationPrivate; |
257 | |
258 | class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject |
259 | { |
260 | //Application level logic, subclassed by Qt Quick if available via QQmlGuiProvider |
261 | Q_OBJECT |
262 | Q_PROPERTY(QStringList arguments READ args CONSTANT) |
263 | Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) |
264 | Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged) |
265 | Q_PROPERTY(QString organization READ organization WRITE setOrganization NOTIFY organizationChanged) |
266 | Q_PROPERTY(QString domain READ domain WRITE setDomain NOTIFY domainChanged) |
267 | QML_ANONYMOUS |
268 | QML_ADDED_IN_VERSION(2, 0) |
269 | public: |
270 | QQmlApplication(QObject* parent=nullptr); |
271 | |
272 | QStringList args(); |
273 | |
274 | QString name() const; |
275 | QString version() const; |
276 | QString organization() const; |
277 | QString domain() const; |
278 | |
279 | public Q_SLOTS: |
280 | void setName(const QString &arg); |
281 | void setVersion(const QString &arg); |
282 | void setOrganization(const QString &arg); |
283 | void setDomain(const QString &arg); |
284 | |
285 | Q_SIGNALS: |
286 | void aboutToQuit(); |
287 | |
288 | void nameChanged(); |
289 | void versionChanged(); |
290 | void organizationChanged(); |
291 | void domainChanged(); |
292 | |
293 | protected: |
294 | QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=nullptr); |
295 | |
296 | private: |
297 | Q_DISABLE_COPY(QQmlApplication) |
298 | Q_DECLARE_PRIVATE(QQmlApplication) |
299 | }; |
300 | |
301 | class QQmlApplicationPrivate : public QObjectPrivate |
302 | { |
303 | Q_DECLARE_PUBLIC(QQmlApplication) |
304 | public: |
305 | QQmlApplicationPrivate() { |
306 | argsInit = false; |
307 | } |
308 | |
309 | bool argsInit; |
310 | QStringList args; |
311 | }; |
312 | |
313 | struct QQmlSourceLocation |
314 | { |
315 | QQmlSourceLocation() {} |
316 | QQmlSourceLocation(const QString &sourceFile, quint16 line, quint16 column) |
317 | : sourceFile(sourceFile), line(line), column(column) {} |
318 | QString sourceFile; |
319 | quint16 line = 0; |
320 | quint16 column = 0; |
321 | }; |
322 | |
323 | QT_END_NAMESPACE |
324 | |
325 | #endif // QQMLGLOBAL_H |
326 | |