1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qqmlinfo.h"
41
42#include "qqmldata_p.h"
43#include "qqmlcontext.h"
44#include "qqmlcontext_p.h"
45#include "qqmlmetatype_p.h"
46#include "qqmlengine_p.h"
47
48#include <QCoreApplication>
49
50QT_BEGIN_NAMESPACE
51
52/*!
53 \namespace QtQml
54 \inmodule QtQml
55 \brief Provides functions for producing logging messages for QML types.
56*/
57
58/*!
59 \fn QQmlInfo QtQml::qmlDebug(const QObject *object)
60 \relates QQmlEngine
61 \since 5.9
62
63 Prints debug messages that include the file and line number for the
64 specified QML \a object.
65
66//! [qqmlinfo-desc]
67 When QML types produce logging messages, it improves traceability
68 if they include the QML file and line number on which the
69 particular instance was instantiated.
70
71 To include the file and line number, an object must be passed. If
72 the file and line number is not available for that instance
73 (either it was not instantiated by the QML engine or location
74 information is disabled), "unknown location" will be used instead.
75//! [qqmlinfo-desc]
76
77 For example,
78
79 \code
80 qmlDebug(object) << "Internal state: 42";
81 \endcode
82
83 prints
84
85 \badcode
86 QML MyCustomType (unknown location): Internal state: 42
87 \endcode
88
89 \sa QtQml::qmlInfo, QtQml::qmlWarning
90*/
91
92/*!
93 \fn QQmlInfo QtQml::qmlInfo(const QObject *object)
94 \relates QQmlEngine
95
96 Prints informational messages that include the file and line number for the
97 specified QML \a object.
98
99 \include qqmlinfo.cpp qqmlinfo-desc
100
101 For example,
102
103 \code
104 qmlInfo(object) << tr("component property is a write-once property");
105 \endcode
106
107 prints
108
109 \badcode
110 QML MyCustomType (unknown location): component property is a write-once property
111 \endcode
112
113 \note In versions prior to Qt 5.9, qmlInfo reported messages using a warning
114 QtMsgType. For Qt 5.9 and above, qmlInfo uses an info QtMsgType. To send
115 warnings, use qmlWarning.
116
117 \sa QtQml::qmlDebug, QtQml::qmlWarning
118*/
119
120/*!
121 \fn QQmlInfo QtQml::qmlWarning(const QObject *object)
122 \relates QQmlEngine
123 \since 5.9
124
125 Prints warning messages that include the file and line number for the
126 specified QML \a object.
127
128 \include qqmlinfo.cpp qqmlinfo-desc
129
130 For example,
131
132 \code
133 qmlInfo(object) << tr("property cannot be set to 0");
134 \endcode
135
136 prints
137
138 \badcode
139 QML MyCustomType (unknown location): property cannot be set to 0
140 \endcode
141
142 \sa QtQml::qmlDebug, QtQml::qmlInfo
143*/
144
145/*!
146 \fn QQmlInfo QtQml::qmlDebug(const QObject *object, const QQmlError &error)
147 \internal
148*/
149
150/*!
151 \fn QQmlInfo QtQml::qmlDebug(const QObject *object, const QList<QQmlError> &errors)
152 \internal
153*/
154
155/*!
156 \fn QQmlInfo QtQml::qmlInfo(const QObject *object, const QQmlError &error)
157 \internal
158*/
159
160/*!
161 \fn QQmlInfo QtQml::qmlInfo(const QObject *object, const QList<QQmlError> &errors)
162 \internal
163*/
164
165/*!
166 \fn QQmlInfo QtQml::qmlWarning(const QObject *object, const QQmlError &error)
167 \internal
168*/
169
170/*!
171 \fn QQmlInfo QtQml::qmlWarning(const QObject *object, const QList<QQmlError> &errors)
172 \internal
173*/
174
175class QQmlInfoPrivate
176{
177public:
178 QQmlInfoPrivate(QtMsgType type)
179 : ref (1)
180 , msgType(type)
181 , object(nullptr)
182 {}
183
184 int ref;
185 QtMsgType msgType;
186 const QObject *object;
187 QString buffer;
188 QList<QQmlError> errors;
189};
190
191QQmlInfo::QQmlInfo(QQmlInfoPrivate *p)
192: QDebug(&p->buffer), d(p)
193{
194 nospace();
195}
196
197QQmlInfo::QQmlInfo(const QQmlInfo &other)
198: QDebug(other), d(other.d)
199{
200 d->ref++;
201}
202
203QQmlInfo::~QQmlInfo()
204{
205 if (0 == --d->ref) {
206 QList<QQmlError> errors = d->errors;
207
208 QQmlEngine *engine = nullptr;
209
210 if (!d->buffer.isEmpty()) {
211 QQmlError error;
212 error.setMessageType(d->msgType);
213
214 QObject *object = const_cast<QObject *>(d->object);
215
216 if (object) {
217 engine = qmlEngine(d->object);
218
219 d->buffer.prepend(QLatin1String("QML ") + QQmlMetaType::prettyTypeName(object) + QLatin1String(": "));
220
221 QQmlData *ddata = QQmlData::get(object, false);
222 if (ddata && ddata->outerContext) {
223 error.setUrl(ddata->outerContext->url());
224 error.setLine(ddata->lineNumber);
225 error.setColumn(ddata->columnNumber);
226 }
227 }
228
229 error.setDescription(d->buffer);
230
231 errors.prepend(error);
232 }
233
234 QQmlEnginePrivate::warning(engine, errors);
235
236 delete d;
237 }
238}
239
240namespace QtQml {
241
242#define MESSAGE_FUNCS(FuncName, MessageLevel) \
243 QQmlInfo FuncName(const QObject *me) \
244 { \
245 QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
246 d->object = me; \
247 return QQmlInfo(d); \
248 } \
249 QQmlInfo FuncName(const QObject *me, const QQmlError &error) \
250 { \
251 QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
252 d->object = me; \
253 d->errors << error; \
254 return QQmlInfo(d); \
255 } \
256 QQmlInfo FuncName(const QObject *me, const QList<QQmlError> &errors) \
257 { \
258 QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
259 d->object = me; \
260 d->errors = errors; \
261 return QQmlInfo(d); \
262 }
263
264MESSAGE_FUNCS(qmlDebug, QtMsgType::QtDebugMsg)
265MESSAGE_FUNCS(qmlInfo, QtMsgType::QtInfoMsg)
266MESSAGE_FUNCS(qmlWarning, QtMsgType::QtWarningMsg)
267
268
269} // namespace QtQml
270
271#if QT_DEPRECATED_SINCE(5, 1)
272
273// Also define symbols outside namespace to keep binary compatibility with Qt 5.0
274
275QQmlInfo qmlInfo(const QObject *me)
276{
277 return QtQml::qmlInfo(me);
278}
279
280QQmlInfo qmlInfo(const QObject *me, const QQmlError &error)
281{
282 return QtQml::qmlInfo(me, error);
283}
284
285QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors)
286{
287 return QtQml::qmlInfo(me, errors);
288}
289
290#endif // QT_DEPRECATED_SINCE(5, 1)
291
292QT_END_NAMESPACE
293