src/declarative/qml/qdeclarativecustomparser.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qdeclarativecustomparser_p.h"
+#include "private/qdeclarativecustomparser_p_p.h"
+
+#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativecompiler_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QDeclarativeParser;
+
+/*!
+    \class QDeclarativeCustomParser
+    \brief The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
+    \internal
+
+    By subclassing QDeclarativeCustomParser, you can add a parser for
+    building a particular type.
+
+    The subclass must implement compile() and setCustomData(), and register
+    itself in the meta type system by calling the macro:
+
+    \code
+    QML_REGISTER_CUSTOM_TYPE(Module, MajorVersion, MinorVersion, Name, TypeClass, ParserClass)
+    \endcode
+*/
+
+/*
+    \fn QByteArray QDeclarativeCustomParser::compile(const QList<QDeclarativeCustomParserProperty> & properties)
+
+    The custom parser processes \a properties, and returns
+    a QByteArray containing data meaningful only to the
+    custom parser; the type engine will pass this same data to
+    setCustomData() when making an instance of the data.
+
+    Errors must be reported via the error() functions.
+
+    The QByteArray may be cached between executions of the system, so
+    it must contain correctly-serialized data (not, for example,
+    pointers to stack objects).
+*/
+
+/*
+    \fn void QDeclarativeCustomParser::setCustomData(QObject *object, const QByteArray &data)
+
+    This function sets \a object to have the properties defined
+    by \a data, which is a block of data previously returned by a call
+    to compile().
+
+    Errors should be reported using qmlInfo(object).
+
+    The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
+*/
+
+QDeclarativeCustomParserNode 
+QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root)
+{
+    QDeclarativeCustomParserNode rootNode;
+    rootNode.d->name = root->typeName;
+    rootNode.d->location = root->location.start;
+
+    for(QHash<QByteArray, Property *>::Iterator iter = root->properties.begin();
+        iter != root->properties.end();
+        ++iter) {
+
+        Property *p = *iter;
+
+        rootNode.d->properties << fromProperty(p);
+    }
+
+    if (root->defaultProperty)
+        rootNode.d->properties << fromProperty(root->defaultProperty);
+
+    return rootNode;
+}
+
+QDeclarativeCustomParserProperty 
+QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *p)
+{
+    QDeclarativeCustomParserProperty prop;
+    prop.d->name = p->name;
+    prop.d->isList = (p->values.count() > 1);
+    prop.d->location = p->location.start;
+
+    if (p->value) {
+        QDeclarativeCustomParserNode node = fromObject(p->value);
+        QList<QDeclarativeCustomParserProperty> props = node.properties();
+        for (int ii = 0; ii < props.count(); ++ii)
+            prop.d->values << QVariant::fromValue(props.at(ii));
+    } else {
+        for(int ii = 0; ii < p->values.count(); ++ii) {
+            Value *v = p->values.at(ii);
+            v->type = QDeclarativeParser::Value::Literal;
+
+            if(v->object) {
+                QDeclarativeCustomParserNode node = fromObject(v->object);
+                prop.d->values << QVariant::fromValue(node);
+            } else {
+                prop.d->values << QVariant::fromValue(v->value);
+            }
+
+        }
+    }
+
+    return prop;
+}
+
+QDeclarativeCustomParserNode::QDeclarativeCustomParserNode()
+: d(new QDeclarativeCustomParserNodePrivate)
+{
+}
+
+QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(const QDeclarativeCustomParserNode &other)
+: d(new QDeclarativeCustomParserNodePrivate)
+{
+    *this = other;
+}
+
+QDeclarativeCustomParserNode &QDeclarativeCustomParserNode::operator=(const QDeclarativeCustomParserNode &other)
+{
+    d->name = other.d->name;
+    d->properties = other.d->properties;
+    d->location = other.d->location;
+    return *this;
+}
+
+QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
+{
+    delete d; d = 0;
+}
+
+QByteArray QDeclarativeCustomParserNode::name() const
+{
+    return d->name;
+}
+
+QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties() const
+{
+    return d->properties;
+}
+
+QDeclarativeParser::Location QDeclarativeCustomParserNode::location() const
+{
+    return d->location;
+}
+
+QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty()
+: d(new QDeclarativeCustomParserPropertyPrivate)
+{
+}
+
+QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty(const QDeclarativeCustomParserProperty &other)
+: d(new QDeclarativeCustomParserPropertyPrivate)
+{
+    *this = other;
+}
+
+QDeclarativeCustomParserProperty &QDeclarativeCustomParserProperty::operator=(const QDeclarativeCustomParserProperty &other)
+{
+    d->name = other.d->name;
+    d->isList = other.d->isList;
+    d->values = other.d->values;
+    d->location = other.d->location;
+    return *this;
+}
+
+QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
+{
+    delete d; d = 0;
+}
+
+QByteArray QDeclarativeCustomParserProperty::name() const
+{
+    return d->name;
+}
+
+bool QDeclarativeCustomParserProperty::isList() const
+{
+    return d->isList;
+}
+
+QDeclarativeParser::Location QDeclarativeCustomParserProperty::location() const
+{
+    return d->location;
+}
+
+QList<QVariant> QDeclarativeCustomParserProperty::assignedValues() const
+{
+    return d->values;
+}
+
+void QDeclarativeCustomParser::clearErrors()
+{
+    exceptions.clear();
+}
+
+/*!
+    Reports an error with the given \a description.
+
+    This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().
+
+    An error is generated referring to the position of the element in the source file.
+*/
+void QDeclarativeCustomParser::error(const QString& description)
+{
+    Q_ASSERT(object);
+    QDeclarativeError error;
+    QString exceptionDescription;
+    error.setLine(object->location.start.line);
+    error.setColumn(object->location.start.column);
+    error.setDescription(description);
+    exceptions << error;
+}
+
+/*!
+    Reports an error in parsing \a prop, with the given \a description.
+
+    An error is generated referring to the position of \a node in the source file.
+*/
+void QDeclarativeCustomParser::error(const QDeclarativeCustomParserProperty& prop, const QString& description)
+{
+    QDeclarativeError error;
+    QString exceptionDescription;
+    error.setLine(prop.location().line);
+    error.setColumn(prop.location().column);
+    error.setDescription(description);
+    exceptions << error;
+}
+
+/*!
+    Reports an error in parsing \a node, with the given \a description.
+
+    An error is generated referring to the position of \a node in the source file.
+*/
+void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
+{
+    QDeclarativeError error;
+    QString exceptionDescription;
+    error.setLine(node.location().line);
+    error.setColumn(node.location().column);
+    error.setDescription(description);
+    exceptions << error;
+}
+
+/*!
+    If \a script is a simply enum expression (eg. Text.AlignLeft),
+    returns the integer equivalent (eg. 1).
+
+    Otherwise, returns -1.
+*/
+int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const
+{
+    return compiler->evaluateEnum(script);
+}
+
+QT_END_NAMESPACE