694493703c26333f9dbd3a5e82fe1693d1cf6999
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecustomparser.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdeclarativecustomparser_p.h"
43 #include "qdeclarativecustomparser_p_p.h"
44
45 #include "qdeclarativecompiler_p.h"
46
47 #include <QtCore/qdebug.h>
48
49 QT_BEGIN_NAMESPACE
50
51 using namespace QDeclarativeScript;
52
53 /*!
54     \class QDeclarativeCustomParser
55     \brief The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
56     \internal
57
58     By subclassing QDeclarativeCustomParser, 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 QDeclarativeCustomParser::compile(const QList<QDeclarativeCustomParserProperty> & 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 QDeclarativeCustomParser::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 QDeclarativeCustomParserNode 
97 QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeScript::Object *root)
98 {
99     QDeclarativeCustomParserNode 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 QDeclarativeCustomParserProperty 
114 QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeScript::Property *p)
115 {
116     QDeclarativeCustomParserProperty 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         QDeclarativeCustomParserNode node = fromObject(p->value);
123         QList<QDeclarativeCustomParserProperty> 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 (QDeclarativeScript::Value *v = p->values.first(); v; v = p->values.next(v)) {
128             v->type = QDeclarativeScript::Value::Literal;
129
130             if(v->object) {
131                 QDeclarativeCustomParserNode 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 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode()
144 : d(new QDeclarativeCustomParserNodePrivate)
145 {
146 }
147
148 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(const QDeclarativeCustomParserNode &other)
149 : d(new QDeclarativeCustomParserNodePrivate)
150 {
151     *this = other;
152 }
153
154 QDeclarativeCustomParserNode &QDeclarativeCustomParserNode::operator=(const QDeclarativeCustomParserNode &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 QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
163 {
164     delete d; d = 0;
165 }
166
167 QString QDeclarativeCustomParserNode::name() const
168 {
169     return d->name;
170 }
171
172 QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties() const
173 {
174     return d->properties;
175 }
176
177 QDeclarativeScript::Location QDeclarativeCustomParserNode::location() const
178 {
179     return d->location;
180 }
181
182 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty()
183 : d(new QDeclarativeCustomParserPropertyPrivate)
184 {
185 }
186
187 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty(const QDeclarativeCustomParserProperty &other)
188 : d(new QDeclarativeCustomParserPropertyPrivate)
189 {
190     *this = other;
191 }
192
193 QDeclarativeCustomParserProperty &QDeclarativeCustomParserProperty::operator=(const QDeclarativeCustomParserProperty &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 QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
203 {
204     delete d; d = 0;
205 }
206
207 QString QDeclarativeCustomParserProperty::name() const
208 {
209     return d->name;
210 }
211
212 bool QDeclarativeCustomParserProperty::isList() const
213 {
214     return d->isList;
215 }
216
217 QDeclarativeScript::Location QDeclarativeCustomParserProperty::location() const
218 {
219     return d->location;
220 }
221
222 QList<QVariant> QDeclarativeCustomParserProperty::assignedValues() const
223 {
224     return d->values;
225 }
226
227 void QDeclarativeCustomParser::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 QDeclarativeCustomParser::error(const QString& description)
240 {
241     Q_ASSERT(object);
242     QDeclarativeError 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 QDeclarativeCustomParser::error(const QDeclarativeCustomParserProperty& prop, const QString& description)
256 {
257     QDeclarativeError 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 QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
271 {
272     QDeclarativeError 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 QDeclarativeCustomParser::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 *QDeclarativeCustomParser::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 QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QDeclarativeScript::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 QDeclarativeCustomParser::rewriteSignalHandler(const QString &handler, const QString &name)
315 {
316     return compiler->rewriteSignalHandler(handler, name);
317 }
318
319 QT_END_NAMESPACE