static void populateRuleComponentModel(RuleComponentModel *component, QmlObject::Ptr object, const QMap<QString, QmlObject::Ptr> &mappers) { if (!component) { return; } for (int i = 0; i < component->count(); ++i) { QVariant type = component->data(component->index(i), RuleComponentModel::Type); MetaProperty *meta = type.value<MetaProperty *>(); if (meta) { QString key = meta->name(); if (object->hasProperty(key)) { // TODO: migrate to MetaProperty QVariant value = object->property(key); if (value.canConvert<Reference::Ptr>()) { Reference::Ptr reference = value.value<Reference::Ptr>(); if (mappers.contains(reference->identifier())) { // Check mapper QmlObject::Ptr mapper = mappers.value(reference->identifier()); if (mapper->type() == "TimeMapper") { int hour = mapper->property("hour").toInt(); int minute = mapper->property("minute").toInt(); QTime time = QTime(hour, minute); component->setValue(i, QVariant(time)); } } } else { component->setValue(i, value); } } } } }
void RulesModel::reload() { if (!m_data.isEmpty()) { beginRemoveRows(QModelIndex(), 0, rowCount() - 1); qDeleteAll(m_data); m_data.clear(); endRemoveRows(); } QStringList rules = m_proxy->Rules(); for (const QString &rule : rules) { bool valid = true; // Parse rule QmlDocument::Ptr doc = QmlDocument::create(rule); if (doc->error() == QmlDocument::NoError) { RuleDefinition *ruleDefinition = new RuleDefinition(this); QmlObject::Ptr root = doc->rootObject(); // 1. Get a list of mappers QMap<QString, QmlObject::Ptr> mappers; if (root->hasProperty("mappers")) { QVariantList mappersVariant = root->property("mappers").toList(); for (const QVariant &mapperVariant : mappersVariant) { if (mapperVariant.canConvert<QmlObject::Ptr>()) { QmlObject::Ptr mapper = mapperVariant.value<QmlObject::Ptr>(); mappers.insert(mapper->id(), mapper); } } } // 2. Name QString name = root->property("name").toString(); // 3. Trigger and condition QString triggerType; if (root->hasProperty("trigger")) { QmlObject::Ptr trigger = root->property("trigger").value<QmlObject::Ptr>(); if (!trigger.isNull()) { triggerType = trigger->type(); RuleComponentModel *triggerComponent = ruleDefinition->createTempComponent(PhoneBotHelper::Trigger, -1, triggerType); populateRuleComponentModel(triggerComponent, trigger, mappers); valid = triggerComponent; } } QString conditionType; if (root->hasProperty("condition")) { QmlObject::Ptr condition = root->property("condition").value<QmlObject::Ptr>(); if (!condition.isNull()) { conditionType = condition->type(); RuleComponentModel *conditionComponent = ruleDefinition->createTempComponent(PhoneBotHelper::Condition, -1, conditionType); populateRuleComponentModel(conditionComponent, condition, mappers); valid = valid && conditionComponent; } } ruleDefinition->saveComponent(-1); ruleDefinition->setName(name); // 4. Actions if (root->hasProperty("actions")) { QVariantList actionsVariant = root->property("actions").toList(); RuleDefinitionActionModel *actions = ruleDefinition->actions(); for (const QVariant &actionVariant : actionsVariant) { if (actionVariant.canConvert<QmlObject::Ptr>()) { int index = actions->count(); QmlObject::Ptr action = actionVariant.value<QmlObject::Ptr>(); RuleComponentModel *actionModel = actions->createTempComponent(PhoneBotHelper::Action, index, action->type()); populateRuleComponentModel(actionModel, action, mappers); actions->saveComponent(index); valid = valid && actionModel; } } } // 5. Save everything RulesModelData *data = new RulesModelData; data->path = rule; data->definition = ruleDefinition; data->valid = valid; m_data.append(data); } } beginInsertRows(QModelIndex(), 0, m_data.count() - 1); emit countChanged(); endInsertRows(); }
void TstParser::parseRule() { QString fileName = ":/simpletest.qml"; QmlDocument::Ptr document = QmlDocument::create(fileName); QVERIFY(!document.isNull()); QCOMPARE(document->fileName(), fileName); // Verify imports QCOMPARE(document->imports().count(), 4); ImportStatement::Ptr import = document->imports()[0]; QCOMPARE(import->importUri(), QString("QtQuick")); QVERIFY(import->importFile().isEmpty()); QCOMPARE(import->version(), QString("2.0")); QVERIFY(import->importId().isEmpty()); import = document->imports()[1]; QVERIFY(import->importUri().isEmpty()); QCOMPARE(import->importFile(), QString("Test.qml")); QCOMPARE(import->version(), QString("1.0")); QCOMPARE(import->importId(), QString("Test")); import = document->imports()[2]; QCOMPARE(import->importUri(), QString("QtQuick")); QVERIFY(import->importFile().isEmpty()); QCOMPARE(import->version(), QString("2.0")); QCOMPARE(import->importId(), QString("QQ")); import = document->imports()[3]; QVERIFY(import->importUri().isEmpty()); QCOMPARE(import->importFile(), QString("Test.qml")); QVERIFY(import->version().isEmpty()); QVERIFY(import->importId().isEmpty()); QmlObject::Ptr root = document->rootObject(); QVERIFY(!root.isNull()); QCOMPARE(root->properties().count(), 6); QCOMPARE(root->type(), QString("Rectangle")); QCOMPARE(root->id(), QString("test")); // Properties QVERIFY(root->hasProperty("width")); QCOMPARE(root->property("width"), QVariant(100)); QVERIFY(root->hasProperty("text")); QCOMPARE(root->property("text"), QVariant("Test")); QVERIFY(root->hasProperty("item")); QmlObject::Ptr item = root->property("item").value<QmlObject::Ptr>(); QVERIFY(!item.isNull()); QCOMPARE(item->type(), QString("Item")); QCOMPARE(item->id(), QString("subTest")); QVERIFY(root->hasProperty("anchors.top")); QVariant anchorsTopProperty = root->property("anchors.top"); QVERIFY(anchorsTopProperty.canConvert<Reference>()); QCOMPARE(anchorsTopProperty.value<Reference>().value(), QString("parent.top")); QVERIFY(root->hasProperty("js")); QVariant jsProperty = root->property("js"); QVERIFY(jsProperty.canConvert<Expression>()); QCOMPARE(jsProperty.value<Expression>().value(), QString("new Date(1960, 1, 1)")); QVERIFY(root->hasProperty("array")); // Children QCOMPARE(root->children().count(), 2); QmlObject::Ptr child = root->children().first(); QVERIFY(!child.isNull()); QCOMPARE(child->type(), QString("Text")); QCOMPARE(child->properties().count(), 1); QVERIFY(child->hasProperty("text")); QCOMPARE(child->property("text").toString(), QString("Test 2")); child = root->children()[1]; QCOMPARE(child->type(), QString("Test")); QCOMPARE(child->properties().count(), 1); QVERIFY(child->hasProperty("test.anchors.left")); QVariant testAnchorsLeft = child->property("test.anchors.left"); QVERIFY(testAnchorsLeft.canConvert<Reference>()); QCOMPARE(testAnchorsLeft.value<Reference>().value(), QString("test.anchors.right")); }