1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "qqmlcustomparser_p.h"
43 #include "qqmlcustomparser_p_p.h"
45 #include "qqmlcompiler_p.h"
47 #include <QtCore/qdebug.h>
51 using namespace QQmlScript;
54 \class QQmlCustomParser
55 \brief The QQmlCustomParser class allows you to add new arbitrary types to QML.
58 By subclassing QQmlCustomParser, 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 QQmlCustomParser::compile(const QList<QQmlCustomParserProperty> & 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 QQmlCustomParser::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.
97 QQmlCustomParserNodePrivate::fromObject(QQmlScript::Object *root)
99 QQmlCustomParserNode 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 QQmlCustomParserProperty
114 QQmlCustomParserNodePrivate::fromProperty(QQmlScript::Property *p)
116 QQmlCustomParserProperty prop;
117 prop.d->name = p->name().toString();
118 prop.d->isList = p->values.isMany();
119 prop.d->location = p->location.start;
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));
127 for (QQmlScript::Value *v = p->values.first(); v; v = p->values.next(v)) {
128 v->type = QQmlScript::Value::Literal;
131 QQmlCustomParserNode node = fromObject(v->object);
132 prop.d->values << QVariant::fromValue(node);
134 prop.d->values << QVariant::fromValue(v->value);
143 QQmlCustomParserNode::QQmlCustomParserNode()
144 : d(new QQmlCustomParserNodePrivate)
148 QQmlCustomParserNode::QQmlCustomParserNode(const QQmlCustomParserNode &other)
149 : d(new QQmlCustomParserNodePrivate)
154 QQmlCustomParserNode &QQmlCustomParserNode::operator=(const QQmlCustomParserNode &other)
156 d->name = other.d->name;
157 d->properties = other.d->properties;
158 d->location = other.d->location;
162 QQmlCustomParserNode::~QQmlCustomParserNode()
167 QString QQmlCustomParserNode::name() const
172 QList<QQmlCustomParserProperty> QQmlCustomParserNode::properties() const
174 return d->properties;
177 QQmlScript::Location QQmlCustomParserNode::location() const
182 QQmlCustomParserProperty::QQmlCustomParserProperty()
183 : d(new QQmlCustomParserPropertyPrivate)
187 QQmlCustomParserProperty::QQmlCustomParserProperty(const QQmlCustomParserProperty &other)
188 : d(new QQmlCustomParserPropertyPrivate)
193 QQmlCustomParserProperty &QQmlCustomParserProperty::operator=(const QQmlCustomParserProperty &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 QQmlCustomParserProperty::~QQmlCustomParserProperty()
207 QString QQmlCustomParserProperty::name() const
212 bool QQmlCustomParserProperty::isList() const
217 QQmlScript::Location QQmlCustomParserProperty::location() const
222 QList<QVariant> QQmlCustomParserProperty::assignedValues() const
227 void QQmlCustomParser::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 QQmlCustomParser::error(const QString& description)
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 QQmlCustomParser::error(const QQmlCustomParserProperty& prop, const QString& description)
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 QQmlCustomParser::error(const QQmlCustomParserNode& node, const QString& description)
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 QQmlCustomParser::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 *QQmlCustomParser::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 QQmlBinding::Identifier QQmlCustomParser::rewriteBinding(const QQmlScript::Variant &value, const QString& name)
307 return compiler->rewriteBinding(value, name);
311 Returns a rewritten \a handler. \a name
312 is used as the name of the rewritten function.
314 QString QQmlCustomParser::rewriteSignalHandler(const QQmlScript::Variant &value, const QString &name)
316 return compiler->rewriteSignalHandler(value , name);