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) { QDeclarativeParser::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; }
bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data) { QList<QVariant> values = prop.assignedValues(); for(int ii = 0; ii < values.count(); ++ii) { const QVariant &value = values.at(ii); if(value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) { QDeclarativeCustomParserNode node = qvariant_cast<QDeclarativeCustomParserNode>(value); if (node.name() != listElementTypeName) { const QMetaObject *mo = resolveType(node.name()); if (mo != &QDeclarativeListElement::staticMetaObject) { error(node, QDeclarativeListModel::tr("ListElement: cannot contain nested elements")); return false; } listElementTypeName = node.name(); // cache right name for next time } { ListInstruction li; li.type = ListInstruction::Push; li.dataIdx = -1; instr << li; } QList<QDeclarativeCustomParserProperty> props = node.properties(); for(int jj = 0; jj < props.count(); ++jj) { const QDeclarativeCustomParserProperty &nodeProp = props.at(jj); if (nodeProp.name().isEmpty()) { error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot contain nested elements")); return false; } if (nodeProp.name() == "id") { error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot use reserved \"id\" property")); return false; } ListInstruction li; int ref = data.count(); data.append(nodeProp.name()); data.append('\0'); li.type = ListInstruction::Set; li.dataIdx = ref; instr << li; if(!compileProperty(nodeProp, instr, data)) return false; li.type = ListInstruction::Pop; li.dataIdx = -1; instr << li; } { ListInstruction li; li.type = ListInstruction::Pop; li.dataIdx = -1; instr << li; } } else { QDeclarativeParser::Variant variant = qvariant_cast<QDeclarativeParser::Variant>(value); int ref = data.count(); QByteArray d; d += char(variant.type()); // type tag if (variant.isString()) { d += variant.asString().toUtf8(); } else if (variant.isNumber()) { d += QByteArray::number(variant.asNumber(),'g',20); } else if (variant.isBoolean()) { d += char(variant.asBoolean()); } else if (variant.isScript()) { if (definesEmptyList(variant.asScript())) { d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list } else { QByteArray script = variant.asScript().toUtf8(); int v = evaluateEnum(script); if (v<0) { if (script.startsWith("QT_TR_NOOP(\"") && script.endsWith("\")")) { d[0] = char(QDeclarativeParser::Variant::String); d += script.mid(12,script.length()-14); } else { error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); return false; } } else { d[0] = char(QDeclarativeParser::Variant::Number); d += QByteArray::number(v); } } } d.append('\0'); data.append(d); ListInstruction li; li.type = ListInstruction::Value; li.dataIdx = ref; instr << li; } } return true; }