1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "qdeclarativecustomparser_p.h"
43 #include "qdeclarativecustomparser_p_p.h"
45 #include "qdeclarativecompiler_p.h"
47 #include <QtCore/qdebug.h>
51 using namespace QDeclarativeScript;
54 \class QDeclarativeCustomParser
55 \brief The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
58 By subclassing QDeclarativeCustomParser, you can add a parser for
59 building a particular type.
61 The subclass must implement compile() and setCustomData(), and register
62 itself in the meta type system by calling the macro:
65 QML_REGISTER_CUSTOM_TYPE(Module, MajorVersion, MinorVersion, Name, TypeClass, ParserClass)
70 \fn QByteArray QDeclarativeCustomParser::compile(const QList<QDeclarativeCustomParserProperty> & properties)
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.
77 Errors must be reported via the error() functions.
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).
85 \fn void QDeclarativeCustomParser::setCustomData(QObject *object, const QByteArray &data)
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
91 Errors should be reported using qmlInfo(object).
93 The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
96 QDeclarativeCustomParserNode
97 QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeScript::Object *root)
99 QDeclarativeCustomParserNode rootNode;
100 rootNode.d->name = root->typeName;
101 rootNode.d->location = root->location.start;
103 for (Property *p = root->properties.first(); p; p = root->properties.next(p)) {
104 rootNode.d->properties << fromProperty(p);
107 if (root->defaultProperty)
108 rootNode.d->properties << fromProperty(root->defaultProperty);
113 QDeclarativeCustomParserProperty
114 QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeScript::Property *p)
116 QDeclarativeCustomParserProperty prop;
117 prop.d->name = p->name().toString();
118 prop.d->isList = p->values.isMany();
119 prop.d->location = p->location.start;
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));
127 for (QDeclarativeScript::Value *v = p->values.first(); v; v = p->values.next(v)) {
128 v->type = QDeclarativeScript::Value::Literal;
131 QDeclarativeCustomParserNode node = fromObject(v->object);
132 prop.d->values << QVariant::fromValue(node);
134 prop.d->values << QVariant::fromValue(v->value);
143 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode()
144 : d(new QDeclarativeCustomParserNodePrivate)
148 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(const QDeclarativeCustomParserNode &other)
149 : d(new QDeclarativeCustomParserNodePrivate)
154 QDeclarativeCustomParserNode &QDeclarativeCustomParserNode::operator=(const QDeclarativeCustomParserNode &other)
156 d->name = other.d->name;
157 d->properties = other.d->properties;
158 d->location = other.d->location;
162 QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
167 QString QDeclarativeCustomParserNode::name() const
172 QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties() const
174 return d->properties;
177 QDeclarativeScript::Location QDeclarativeCustomParserNode::location() const
182 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty()
183 : d(new QDeclarativeCustomParserPropertyPrivate)
187 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty(const QDeclarativeCustomParserProperty &other)
188 : d(new QDeclarativeCustomParserPropertyPrivate)
193 QDeclarativeCustomParserProperty &QDeclarativeCustomParserProperty::operator=(const QDeclarativeCustomParserProperty &other)
195 d->name = other.d->name;
196 d->isList = other.d->isList;
197 d->values = other.d->values;
198 d->location = other.d->location;
202 QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
207 QString QDeclarativeCustomParserProperty::name() const
212 bool QDeclarativeCustomParserProperty::isList() const
217 QDeclarativeScript::Location QDeclarativeCustomParserProperty::location() const
222 QList<QVariant> QDeclarativeCustomParserProperty::assignedValues() const
227 void QDeclarativeCustomParser::clearErrors()
233 Reports an error with the given \a description.
235 This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().
237 An error is generated referring to the position of the element in the source file.
239 void QDeclarativeCustomParser::error(const QString& description)
242 QDeclarativeError error;
243 QString exceptionDescription;
244 error.setLine(object->location.start.line);
245 error.setColumn(object->location.start.column);
246 error.setDescription(description);
251 Reports an error in parsing \a prop, with the given \a description.
253 An error is generated referring to the position of \a node in the source file.
255 void QDeclarativeCustomParser::error(const QDeclarativeCustomParserProperty& prop, const QString& description)
257 QDeclarativeError error;
258 QString exceptionDescription;
259 error.setLine(prop.location().line);
260 error.setColumn(prop.location().column);
261 error.setDescription(description);
266 Reports an error in parsing \a node, with the given \a description.
268 An error is generated referring to the position of \a node in the source file.
270 void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
272 QDeclarativeError error;
273 QString exceptionDescription;
274 error.setLine(node.location().line);
275 error.setColumn(node.location().column);
276 error.setDescription(description);
281 If \a script is a simply enum expression (eg. Text.AlignLeft),
282 returns the integer equivalent (eg. 1).
284 Otherwise, returns -1.
286 int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const
288 return compiler->evaluateEnum(script);
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.
295 const QMetaObject *QDeclarativeCustomParser::resolveType(const QString& name) const
297 return compiler->resolveType(name);
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.
305 QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QDeclarativeScript::Variant &value, const QString& name)
307 return compiler->rewriteBinding(value, name);