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 "private/qdeclarativecustomparser_p.h"
43 #include "private/qdeclarativecustomparser_p_p.h"
45 #include "private/qdeclarativeparser_p.h"
46 #include "private/qdeclarativecompiler_p.h"
48 #include <QtCore/qdebug.h>
52 using namespace QDeclarativeParser;
55 \class QDeclarativeCustomParser
56 \brief The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
59 By subclassing QDeclarativeCustomParser, you can add a parser for
60 building a particular type.
62 The subclass must implement compile() and setCustomData(), and register
63 itself in the meta type system by calling the macro:
66 QML_REGISTER_CUSTOM_TYPE(Module, MajorVersion, MinorVersion, Name, TypeClass, ParserClass)
71 \fn QByteArray QDeclarativeCustomParser::compile(const QList<QDeclarativeCustomParserProperty> & properties)
73 The custom parser processes \a properties, and returns
74 a QByteArray containing data meaningful only to the
75 custom parser; the type engine will pass this same data to
76 setCustomData() when making an instance of the data.
78 Errors must be reported via the error() functions.
80 The QByteArray may be cached between executions of the system, so
81 it must contain correctly-serialized data (not, for example,
82 pointers to stack objects).
86 \fn void QDeclarativeCustomParser::setCustomData(QObject *object, const QByteArray &data)
88 This function sets \a object to have the properties defined
89 by \a data, which is a block of data previously returned by a call
92 Errors should be reported using qmlInfo(object).
94 The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
97 QDeclarativeCustomParserNode
98 QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root)
100 QDeclarativeCustomParserNode rootNode;
101 rootNode.d->name = root->typeName;
102 rootNode.d->location = root->location.start;
104 for(QHash<QByteArray, Property *>::Iterator iter = root->properties.begin();
105 iter != root->properties.end();
110 rootNode.d->properties << fromProperty(p);
113 if (root->defaultProperty)
114 rootNode.d->properties << fromProperty(root->defaultProperty);
119 QDeclarativeCustomParserProperty
120 QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *p)
122 QDeclarativeCustomParserProperty prop;
123 prop.d->name = p->name;
124 prop.d->isList = (p->values.count() > 1);
125 prop.d->location = p->location.start;
128 QDeclarativeCustomParserNode node = fromObject(p->value);
129 QList<QDeclarativeCustomParserProperty> props = node.properties();
130 for (int ii = 0; ii < props.count(); ++ii)
131 prop.d->values << QVariant::fromValue(props.at(ii));
133 for(int ii = 0; ii < p->values.count(); ++ii) {
134 QDeclarativeParser::Value *v = p->values.at(ii);
135 v->type = QDeclarativeParser::Value::Literal;
138 QDeclarativeCustomParserNode node = fromObject(v->object);
139 prop.d->values << QVariant::fromValue(node);
141 prop.d->values << QVariant::fromValue(v->value);
150 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode()
151 : d(new QDeclarativeCustomParserNodePrivate)
155 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(const QDeclarativeCustomParserNode &other)
156 : d(new QDeclarativeCustomParserNodePrivate)
161 QDeclarativeCustomParserNode &QDeclarativeCustomParserNode::operator=(const QDeclarativeCustomParserNode &other)
163 d->name = other.d->name;
164 d->properties = other.d->properties;
165 d->location = other.d->location;
169 QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
174 QByteArray QDeclarativeCustomParserNode::name() const
179 QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties() const
181 return d->properties;
184 QDeclarativeParser::Location QDeclarativeCustomParserNode::location() const
189 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty()
190 : d(new QDeclarativeCustomParserPropertyPrivate)
194 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty(const QDeclarativeCustomParserProperty &other)
195 : d(new QDeclarativeCustomParserPropertyPrivate)
200 QDeclarativeCustomParserProperty &QDeclarativeCustomParserProperty::operator=(const QDeclarativeCustomParserProperty &other)
202 d->name = other.d->name;
203 d->isList = other.d->isList;
204 d->values = other.d->values;
205 d->location = other.d->location;
209 QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
214 QByteArray QDeclarativeCustomParserProperty::name() const
219 bool QDeclarativeCustomParserProperty::isList() const
224 QDeclarativeParser::Location QDeclarativeCustomParserProperty::location() const
229 QList<QVariant> QDeclarativeCustomParserProperty::assignedValues() const
234 void QDeclarativeCustomParser::clearErrors()
240 Reports an error with the given \a description.
242 This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().
244 An error is generated referring to the position of the element in the source file.
246 void QDeclarativeCustomParser::error(const QString& description)
249 QDeclarativeError error;
250 QString exceptionDescription;
251 error.setLine(object->location.start.line);
252 error.setColumn(object->location.start.column);
253 error.setDescription(description);
258 Reports an error in parsing \a prop, with the given \a description.
260 An error is generated referring to the position of \a node in the source file.
262 void QDeclarativeCustomParser::error(const QDeclarativeCustomParserProperty& prop, const QString& description)
264 QDeclarativeError error;
265 QString exceptionDescription;
266 error.setLine(prop.location().line);
267 error.setColumn(prop.location().column);
268 error.setDescription(description);
273 Reports an error in parsing \a node, with the given \a description.
275 An error is generated referring to the position of \a node in the source file.
277 void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
279 QDeclarativeError error;
280 QString exceptionDescription;
281 error.setLine(node.location().line);
282 error.setColumn(node.location().column);
283 error.setDescription(description);
288 If \a script is a simply enum expression (eg. Text.AlignLeft),
289 returns the integer equivalent (eg. 1).
291 Otherwise, returns -1.
293 int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const
295 return compiler->evaluateEnum(script);
299 Resolves \a name to a type, or 0 if it is not a type. This can be used
300 to type-check object nodes.
302 const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name) const
304 return compiler->resolveType(name);
308 Rewrites \a expression and returns an identifier that can be
309 used to construct the binding later. \a name
310 is used as the name of the rewritten function.
312 QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QString& expression, const QByteArray& name)
314 return compiler->rewriteBinding(expression, name);