Rename QDeclarative symbols to QQuick and QQml
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmlcustomparser.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qqmlcustomparser_p.h"
43 #include "qqmlcustomparser_p_p.h"
44
45 #include "qqmlcompiler_p.h"
46
47 #include <QtCore/qdebug.h>
48
49 QT_BEGIN_NAMESPACE
50
51 using namespace QQmlScript;
52
53 /*!
54     \class QQmlCustomParser
55     \brief The QQmlCustomParser class allows you to add new arbitrary types to QML.
56     \internal
57
58     By subclassing QQmlCustomParser, you can add a parser for
59     building a particular type.
60
61     The subclass must implement compile() and setCustomData(), and register
62     itself in the meta type system by calling the macro:
63
64     \code
65     QML_REGISTER_CUSTOM_TYPE(Module, MajorVersion, MinorVersion, Name, TypeClass, ParserClass)
66     \endcode
67 */
68
69 /*
70     \fn QByteArray QQmlCustomParser::compile(const QList<QQmlCustomParserProperty> & properties)
71
72     The custom parser processes \a properties, and returns
73     a QByteArray containing data meaningful only to the
74     custom parser; the type engine will pass this same data to
75     setCustomData() when making an instance of the data.
76
77     Errors must be reported via the error() functions.
78
79     The QByteArray may be cached between executions of the system, so
80     it must contain correctly-serialized data (not, for example,
81     pointers to stack objects).
82 */
83
84 /*
85     \fn void QQmlCustomParser::setCustomData(QObject *object, const QByteArray &data)
86
87     This function sets \a object to have the properties defined
88     by \a data, which is a block of data previously returned by a call
89     to compile().
90
91     Errors should be reported using qmlInfo(object).
92
93     The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
94 */
95
96 QQmlCustomParserNode 
97 QQmlCustomParserNodePrivate::fromObject(QQmlScript::Object *root)
98 {
99     QQmlCustomParserNode rootNode;
100     rootNode.d->name = root->typeName;
101     rootNode.d->location = root->location.start;
102
103     for (Property *p = root->properties.first(); p; p = root->properties.next(p)) {
104         rootNode.d->properties << fromProperty(p);
105     }
106
107     if (root->defaultProperty)
108         rootNode.d->properties << fromProperty(root->defaultProperty);
109
110     return rootNode;
111 }
112
113 QQmlCustomParserProperty 
114 QQmlCustomParserNodePrivate::fromProperty(QQmlScript::Property *p)
115 {
116     QQmlCustomParserProperty prop;
117     prop.d->name = p->name().toString();
118     prop.d->isList = p->values.isMany();
119     prop.d->location = p->location.start;
120
121     if (p->value) {
122         QQmlCustomParserNode node = fromObject(p->value);
123         QList<QQmlCustomParserProperty> props = node.properties();
124         for (int ii = 0; ii < props.count(); ++ii)
125             prop.d->values << QVariant::fromValue(props.at(ii));
126     } else {
127         for (QQmlScript::Value *v = p->values.first(); v; v = p->values.next(v)) {
128             v->type = QQmlScript::Value::Literal;
129
130             if(v->object) {
131                 QQmlCustomParserNode node = fromObject(v->object);
132                 prop.d->values << QVariant::fromValue(node);
133             } else {
134                 prop.d->values << QVariant::fromValue(v->value);
135             }
136
137         }
138     }
139
140     return prop;
141 }
142
143 QQmlCustomParserNode::QQmlCustomParserNode()
144 : d(new QQmlCustomParserNodePrivate)
145 {
146 }
147
148 QQmlCustomParserNode::QQmlCustomParserNode(const QQmlCustomParserNode &other)
149 : d(new QQmlCustomParserNodePrivate)
150 {
151     *this = other;
152 }
153
154 QQmlCustomParserNode &QQmlCustomParserNode::operator=(const QQmlCustomParserNode &other)
155 {
156     d->name = other.d->name;
157     d->properties = other.d->properties;
158     d->location = other.d->location;
159     return *this;
160 }
161
162 QQmlCustomParserNode::~QQmlCustomParserNode()
163 {
164     delete d; d = 0;
165 }
166
167 QString QQmlCustomParserNode::name() const
168 {
169     return d->name;
170 }
171
172 QList<QQmlCustomParserProperty> QQmlCustomParserNode::properties() const
173 {
174     return d->properties;
175 }
176
177 QQmlScript::Location QQmlCustomParserNode::location() const
178 {
179     return d->location;
180 }
181
182 QQmlCustomParserProperty::QQmlCustomParserProperty()
183 : d(new QQmlCustomParserPropertyPrivate)
184 {
185 }
186
187 QQmlCustomParserProperty::QQmlCustomParserProperty(const QQmlCustomParserProperty &other)
188 : d(new QQmlCustomParserPropertyPrivate)
189 {
190     *this = other;
191 }
192
193 QQmlCustomParserProperty &QQmlCustomParserProperty::operator=(const QQmlCustomParserProperty &other)
194 {
195     d->name = other.d->name;
196     d->isList = other.d->isList;
197     d->values = other.d->values;
198     d->location = other.d->location;
199     return *this;
200 }
201
202 QQmlCustomParserProperty::~QQmlCustomParserProperty()
203 {
204     delete d; d = 0;
205 }
206
207 QString QQmlCustomParserProperty::name() const
208 {
209     return d->name;
210 }
211
212 bool QQmlCustomParserProperty::isList() const
213 {
214     return d->isList;
215 }
216
217 QQmlScript::Location QQmlCustomParserProperty::location() const
218 {
219     return d->location;
220 }
221
222 QList<QVariant> QQmlCustomParserProperty::assignedValues() const
223 {
224     return d->values;
225 }
226
227 void QQmlCustomParser::clearErrors()
228 {
229     exceptions.clear();
230 }
231
232 /*!
233     Reports an error with the given \a description.
234
235     This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().
236
237     An error is generated referring to the position of the element in the source file.
238 */
239 void QQmlCustomParser::error(const QString& description)
240 {
241     Q_ASSERT(object);
242     QQmlError error;
243     QString exceptionDescription;
244     error.setLine(object->location.start.line);
245     error.setColumn(object->location.start.column);
246     error.setDescription(description);
247     exceptions << error;
248 }
249
250 /*!
251     Reports an error in parsing \a prop, with the given \a description.
252
253     An error is generated referring to the position of \a node in the source file.
254 */
255 void QQmlCustomParser::error(const QQmlCustomParserProperty& prop, const QString& description)
256 {
257     QQmlError error;
258     QString exceptionDescription;
259     error.setLine(prop.location().line);
260     error.setColumn(prop.location().column);
261     error.setDescription(description);
262     exceptions << error;
263 }
264
265 /*!
266     Reports an error in parsing \a node, with the given \a description.
267
268     An error is generated referring to the position of \a node in the source file.
269 */
270 void QQmlCustomParser::error(const QQmlCustomParserNode& node, const QString& description)
271 {
272     QQmlError error;
273     QString exceptionDescription;
274     error.setLine(node.location().line);
275     error.setColumn(node.location().column);
276     error.setDescription(description);
277     exceptions << error;
278 }
279
280 /*!
281     If \a script is a simply enum expression (eg. Text.AlignLeft),
282     returns the integer equivalent (eg. 1).
283
284     Otherwise, returns -1.
285 */
286 int QQmlCustomParser::evaluateEnum(const QByteArray& script) const
287 {
288     return compiler->evaluateEnum(script);
289 }
290
291 /*!
292     Resolves \a name to a type, or 0 if it is not a type. This can be used
293     to type-check object nodes.
294 */
295 const QMetaObject *QQmlCustomParser::resolveType(const QString& name) const
296 {
297     return compiler->resolveType(name);
298 }
299
300 /*!
301     Rewrites \a value and returns an identifier that can be
302     used to construct the binding later. \a name
303     is used as the name of the rewritten function.
304 */
305 QQmlBinding::Identifier QQmlCustomParser::rewriteBinding(const QQmlScript::Variant &value, const QString& name)
306 {
307     return compiler->rewriteBinding(value, name);
308 }
309
310 /*!
311     Returns a rewritten \a handler. \a name
312     is used as the name of the rewritten function.
313 */
314 QString QQmlCustomParser::rewriteSignalHandler(const QQmlScript::Variant &value, const QString &name)
315 {
316     return compiler->rewriteSignalHandler(value , name);
317 }
318
319 QT_END_NAMESPACE