src/declarative/qml/qdeclarativecustomparser.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 
       
    50 QT_BEGIN_NAMESPACE
       
    51 
       
    52 using 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 
       
    97 QDeclarativeCustomParserNode 
       
    98 QDeclarativeCustomParserNodePrivate::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 
       
   119 QDeclarativeCustomParserProperty 
       
   120 QDeclarativeCustomParserNodePrivate::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 
       
   150 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode()
       
   151 : d(new QDeclarativeCustomParserNodePrivate)
       
   152 {
       
   153 }
       
   154 
       
   155 QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(const QDeclarativeCustomParserNode &other)
       
   156 : d(new QDeclarativeCustomParserNodePrivate)
       
   157 {
       
   158     *this = other;
       
   159 }
       
   160 
       
   161 QDeclarativeCustomParserNode &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 
       
   169 QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
       
   170 {
       
   171     delete d; d = 0;
       
   172 }
       
   173 
       
   174 QByteArray QDeclarativeCustomParserNode::name() const
       
   175 {
       
   176     return d->name;
       
   177 }
       
   178 
       
   179 QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties() const
       
   180 {
       
   181     return d->properties;
       
   182 }
       
   183 
       
   184 QDeclarativeParser::Location QDeclarativeCustomParserNode::location() const
       
   185 {
       
   186     return d->location;
       
   187 }
       
   188 
       
   189 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty()
       
   190 : d(new QDeclarativeCustomParserPropertyPrivate)
       
   191 {
       
   192 }
       
   193 
       
   194 QDeclarativeCustomParserProperty::QDeclarativeCustomParserProperty(const QDeclarativeCustomParserProperty &other)
       
   195 : d(new QDeclarativeCustomParserPropertyPrivate)
       
   196 {
       
   197     *this = other;
       
   198 }
       
   199 
       
   200 QDeclarativeCustomParserProperty &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 
       
   209 QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
       
   210 {
       
   211     delete d; d = 0;
       
   212 }
       
   213 
       
   214 QByteArray QDeclarativeCustomParserProperty::name() const
       
   215 {
       
   216     return d->name;
       
   217 }
       
   218 
       
   219 bool QDeclarativeCustomParserProperty::isList() const
       
   220 {
       
   221     return d->isList;
       
   222 }
       
   223 
       
   224 QDeclarativeParser::Location QDeclarativeCustomParserProperty::location() const
       
   225 {
       
   226     return d->location;
       
   227 }
       
   228 
       
   229 QList<QVariant> QDeclarativeCustomParserProperty::assignedValues() const
       
   230 {
       
   231     return d->values;
       
   232 }
       
   233 
       
   234 void 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 */
       
   246 void 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 */
       
   262 void 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 */
       
   277 void 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 */
       
   293 int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const
       
   294 {
       
   295     return compiler->evaluateEnum(script);
       
   296 }
       
   297 
       
   298 QT_END_NAMESPACE