source: trunk/src/declarative/qml/qdeclarativecustomparser.cpp@ 883

Last change on this file since 883 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 9.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "private/qdeclarativecustomparser_p.h"
43#include "private/qdeclarativecustomparser_p_p.h"
44
45#include "private/qdeclarativeparser_p.h"
46#include "private/qdeclarativecompiler_p.h"
47
48#include <QtCore/qdebug.h>
49
50QT_BEGIN_NAMESPACE
51
52using namespace QDeclarativeParser;
53
54/*!
55 \class QDeclarativeCustomParser
56 \brief The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
57 \internal
58
59 By subclassing QDeclarativeCustomParser, you can add a parser for
60 building a particular type.
61
62 The subclass must implement compile() and setCustomData(), and register
63 itself in the meta type system by calling the macro:
64
65 \code
66 QML_REGISTER_CUSTOM_TYPE(Module, MajorVersion, MinorVersion, Name, TypeClass, ParserClass)
67 \endcode
68*/
69
70/*
71 \fn QByteArray QDeclarativeCustomParser::compile(const QList<QDeclarativeCustomParserProperty> & properties)
72
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.
77
78 Errors must be reported via the error() functions.
79
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).
83*/
84
85/*
86 \fn void QDeclarativeCustomParser::setCustomData(QObject *object, const QByteArray &data)
87
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
90 to compile().
91
92 Errors should be reported using qmlInfo(object).
93
94 The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
95*/
96
97QDeclarativeCustomParserNode
98QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root)
99{
100 QDeclarativeCustomParserNode rootNode;
101 rootNode.d->name = root->typeName;
102 rootNode.d->location = root->location.start;
103
104 for(QHash<QByteArray, Property *>::Iterator iter = root->properties.begin();
105 iter != root->properties.end();
106 ++iter) {
107
108 Property *p = *iter;
109
110 rootNode.d->properties << fromProperty(p);
111 }
112
113 if (root->defaultProperty)
114 rootNode.d->properties << fromProperty(root->defaultProperty);
115
116 return rootNode;
117}
118
119QDeclarativeCustomParserProperty
120QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *p)
121{
122 QDeclarativeCustomParserProperty prop;
123 prop.d->name = p->name;
124 prop.d->isList = (p->values.count() > 1);
125 prop.d->location = p->location.start;
126
127 if (p->value) {
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));
132 } else {
133 for(int ii = 0; ii < p->values.count(); ++ii) {
134 Value *v = p->values.at(ii);
135 v->type = QDeclarativeParser::Value::Literal;
136
137 if(v->object) {
138 QDeclarativeCustomParserNode node = fromObject(v->object);
139 prop.d->values << QVariant::fromValue(node);
140 } else {
141 prop.d->values << QVariant::fromValue(v->value);
142 }
143
144 }
145 }
146
147 return prop;
148}
149
150QDeclarativeCustomParserNode::QDeclarativeCustomParserNode()
151: d(new QDeclarativeCustomParserNodePrivate)
152{
153}
154
155QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(const QDeclarativeCustomParserNode &other)
156: d(new QDeclarativeCustomParserNodePrivate)
157{
158 *this = other;
159}
160
161QDeclarativeCustomParserNode &QDeclarativeCustomParserNode::operator=(const QDeclarativeCustomParserNode &other)
162{
163 d->name = other.d->name;
164 d->properties = other.d->properties;
165 d->location = other.d->location;
166 return *this;
167}
168
169QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
170{
171 delete d; d = 0;
172}
173
174QByteArray QDeclarativeCustomParserNode::name() const
175{
176 return d->name;
177}
178
179QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties() const
180{
181 return d->properties;
182}
183
184QDeclarativeParser::Location QDeclarativeCustomParserNode::location() const
185{
186 return d->location;
187}
188
189QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty()
190: d(new QDeclarativeCustomParserPropertyPrivate)
191{
192}
193
194QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty(const QDeclarativeCustomParserProperty &other)
195: d(new QDeclarativeCustomParserPropertyPrivate)
196{
197 *this = other;
198}
199
200QDeclarativeCustomParserProperty &QDeclarativeCustomParserProperty::operator=(const QDeclarativeCustomParserProperty &other)
201{
202 d->name = other.d->name;
203 d->isList = other.d->isList;
204 d->values = other.d->values;
205 d->location = other.d->location;
206 return *this;
207}
208
209QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
210{
211 delete d; d = 0;
212}
213
214QByteArray QDeclarativeCustomParserProperty::name() const
215{
216 return d->name;
217}
218
219bool QDeclarativeCustomParserProperty::isList() const
220{
221 return d->isList;
222}
223
224QDeclarativeParser::Location QDeclarativeCustomParserProperty::location() const
225{
226 return d->location;
227}
228
229QList<QVariant> QDeclarativeCustomParserProperty::assignedValues() const
230{
231 return d->values;
232}
233
234void QDeclarativeCustomParser::clearErrors()
235{
236 exceptions.clear();
237}
238
239/*!
240 Reports an error with the given \a description.
241
242 This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().
243
244 An error is generated referring to the position of the element in the source file.
245*/
246void QDeclarativeCustomParser::error(const QString& description)
247{
248 Q_ASSERT(object);
249 QDeclarativeError error;
250 QString exceptionDescription;
251 error.setLine(object->location.start.line);
252 error.setColumn(object->location.start.column);
253 error.setDescription(description);
254 exceptions << error;
255}
256
257/*!
258 Reports an error in parsing \a prop, with the given \a description.
259
260 An error is generated referring to the position of \a node in the source file.
261*/
262void QDeclarativeCustomParser::error(const QDeclarativeCustomParserProperty& prop, const QString& description)
263{
264 QDeclarativeError error;
265 QString exceptionDescription;
266 error.setLine(prop.location().line);
267 error.setColumn(prop.location().column);
268 error.setDescription(description);
269 exceptions << error;
270}
271
272/*!
273 Reports an error in parsing \a node, with the given \a description.
274
275 An error is generated referring to the position of \a node in the source file.
276*/
277void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
278{
279 QDeclarativeError error;
280 QString exceptionDescription;
281 error.setLine(node.location().line);
282 error.setColumn(node.location().column);
283 error.setDescription(description);
284 exceptions << error;
285}
286
287/*!
288 If \a script is a simply enum expression (eg. Text.AlignLeft),
289 returns the integer equivalent (eg. 1).
290
291 Otherwise, returns -1.
292*/
293int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const
294{
295 return compiler->evaluateEnum(script);
296}
297
298/*!
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.
301*/
302const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name) const
303{
304 return compiler->resolveType(name);
305}
306
307
308QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.