static inline void applyProperties(ModelNode &node, const QHash<PropertyName, QVariant> &propertyHash) { QHash<PropertyName, QVariant> auxiliaryData = node.auxiliaryData(); foreach (const PropertyName &propertyName, auxiliaryData.keys()) { if (node.hasAuxiliaryData(propertyName)) node.setAuxiliaryData(propertyName, QVariant()); } QHashIterator<PropertyName, QVariant> propertyIterator(propertyHash); while (propertyIterator.hasNext()) { propertyIterator.next(); const PropertyName propertyName = propertyIterator.key(); if (propertyName == "width" || propertyName == "height") { node.setAuxiliaryData(propertyIterator.key(), propertyIterator.value()); } else if (node.property(propertyIterator.key()).isDynamic() && node.property(propertyIterator.key()).dynamicTypeName() == "alias" && node.property(propertyIterator.key()).isBindingProperty()) { AbstractProperty targetProperty = node.bindingProperty(propertyIterator.key()).resolveToProperty(); if (targetProperty.isValid()) targetProperty.parentModelNode().setAuxiliaryData(targetProperty.name() + "@NodeInstance", propertyIterator.value()); } else { node.setAuxiliaryData(propertyIterator.key() + "@NodeInstance", propertyIterator.value()); } } }
AbstractProperty::AbstractProperty(const AbstractProperty &property, AbstractView *view) : m_propertyName(property.name()), m_internalNode(property.internalNode()), m_model(property.model()), m_view(view) { }
bool detectVerticalCycle(const ModelNode &node, QList<ModelNode> knownNodeList) { if (!node.isValid()) return false; if (knownNodeList.contains(node)) return true; knownNodeList.append(node); static QStringList validAnchorLines(QStringList() << "top" << "bottom" << "verticalCenter" << "baseline"); static QStringList anchorNames(QStringList() << "anchors.top" << "anchors.bottom" << "anchors.verticalCenter" << "anchors.baseline"); foreach (const QString &anchorName, anchorNames) { if (node.hasBindingProperty(anchorName)) { AbstractProperty targetProperty = node.bindingProperty(anchorName).resolveToProperty(); if (targetProperty.isValid()) { if (!validAnchorLines.contains(targetProperty.name())) return true; if (detectVerticalCycle(targetProperty.parentModelNode(), knownNodeList)) return true; } } } static QStringList anchorShortcutNames(QStringList() << "anchors.fill" << "anchors.centerIn"); foreach (const QString &anchorName, anchorShortcutNames) { if (node.hasBindingProperty(anchorName)) { ModelNode targetNode = node.bindingProperty(anchorName).resolveToModelNode(); if (targetNode.isValid() && detectVerticalCycle(targetNode, knownNodeList)) return true; } } return false; }
QVariant PropertyModel::data(const QModelIndex & index, int role) const { if (!index.isValid()) return QVariant(); AbstractProperty * property = retrieveItem(index)->property(); if (role == Qt::DisplayRole && index.column() == 0) { std::string title; if (property->hasOption("title")) title = property->option("title").value<std::string>(); else title = property->name(); return QVariant(QString::fromStdString(title)); } if (role == Qt::ToolTipRole && property->hasOption("tooltip")) return QVariant(QString::fromStdString(property->option("tooltip").value<std::string>())); return QVariant(); }
bool detectHorizontalCycle(const ModelNode &node, QList<ModelNode> knownNodeList) { if (knownNodeList.contains(node)) return true; knownNodeList.append(node); static PropertyNameList validAnchorLines(PropertyNameList() << "right" << "left" << "horizontalCenter"); static PropertyNameList anchorNames(PropertyNameList() << "anchors.right" << "anchors.left" << "anchors.horizontalCenter"); foreach (const PropertyName &anchorName, anchorNames) { if (node.hasBindingProperty(anchorName)) { AbstractProperty targetProperty = node.bindingProperty(anchorName).resolveToProperty(); if (targetProperty.isValid()) { if (!validAnchorLines.contains(targetProperty.name())) return true; if (detectHorizontalCycle(targetProperty.parentModelNode(), knownNodeList)) return true; } } } static PropertyNameList anchorShortcutNames(PropertyNameList() << "anchors.fill" << "anchors.centerIn"); foreach (const PropertyName &anchorName, anchorShortcutNames) { if (node.hasBindingProperty(anchorName)) { ModelNode targetNode = node.bindingProperty(anchorName).resolveToModelNode(); if (targetNode.isValid() && detectHorizontalCycle(targetNode, knownNodeList)) return true; } } return false; }
QDebug operator<<(QDebug debug, const AbstractProperty &property) { return debug.nospace() << "AbstractProperty(" << (property.isValid() ? property.name() : PropertyName("invalid")) << ')'; }
QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDepth) const { if (property.isBindingProperty()) { return property.toBindingProperty().expression(); } else if (property.isNodeProperty()) { return toQml(property.toNodeProperty().modelNode(), indentDepth); } else if (property.isNodeListProperty()) { const QList<ModelNode> nodes = property.toNodeListProperty().toModelNodeList(); if (property.isDefaultProperty()) { QString result; for (int i = 0; i < nodes.length(); ++i) { if (i > 0) result += QLatin1String("\n\n"); result += QString(indentDepth, QLatin1Char(' ')); result += toQml(nodes.at(i), indentDepth); } return result; } else { QString result = QLatin1String("["); const int arrayContentDepth = indentDepth + 4; const QString arrayContentIndentation(arrayContentDepth, QLatin1Char(' ')); for (int i = 0; i < nodes.length(); ++i) { if (i > 0) result += QLatin1Char(','); result += QLatin1Char('\n'); result += arrayContentIndentation; result += toQml(nodes.at(i), arrayContentDepth); } return result + QLatin1Char(']'); } } else if (property.isVariantProperty()) { const VariantProperty variantProperty = property.toVariantProperty(); const QVariant value = variantProperty.value(); const QString stringValue = value.toString(); if (property.name() == QLatin1String("id")) return stringValue; if (false) { } if (variantProperty.parentModelNode().metaInfo().isValid() && variantProperty.parentModelNode().metaInfo().propertyIsEnumType(variantProperty.name())) { return variantProperty.parentModelNode().metaInfo().propertyEnumScope(variantProperty.name()) + '.' + stringValue; } else { switch (value.type()) { case QVariant::Bool: if (value.value<bool>()) return QLatin1String("true"); else return QLatin1String("false"); case QVariant::Color: return QString(QLatin1String("\"%1\"")).arg(properColorName(value.value<QColor>())); case QVariant::Double: return doubleToString(value.toDouble()); case QVariant::Int: case QVariant::LongLong: case QVariant::UInt: case QVariant::ULongLong: return stringValue; default: return QString(QLatin1String("\"%1\"")).arg(escape(stringValue)); } } } else { Q_ASSERT("Unknown property type"); return QString(); } }
// TODO: this need to e updated for states static bool compareProperty(const AbstractProperty &property1, const AbstractProperty &property2) { return (property1.name() == property2.name()); // && (property1.value().type() == property2.value().type()); // && (property1.value() == property2.value())); }
QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDepth) const { if (property.isBindingProperty()) { return property.toBindingProperty().expression(); } else if (property.isSignalHandlerProperty()) { return property.toSignalHandlerProperty().source(); } else if (property.isNodeProperty()) { return toQml(property.toNodeProperty().modelNode(), indentDepth); } else if (property.isNodeListProperty()) { const QList<ModelNode> nodes = property.toNodeListProperty().toModelNodeList(); if (property.isDefaultProperty()) { QString result; for (int i = 0; i < nodes.length(); ++i) { if (i > 0) result += QLatin1String("\n\n"); result += QString(indentDepth, QLatin1Char(' ')); result += toQml(nodes.at(i), indentDepth); } return result; } else { QString result = QLatin1String("["); const int arrayContentDepth = indentDepth + 4; const QString arrayContentIndentation(arrayContentDepth, QLatin1Char(' ')); for (int i = 0; i < nodes.length(); ++i) { if (i > 0) result += QLatin1Char(','); result += QLatin1Char('\n'); result += arrayContentIndentation; result += toQml(nodes.at(i), arrayContentDepth); } return result + QLatin1Char(']'); } } else if (property.isVariantProperty()) { const VariantProperty variantProperty = property.toVariantProperty(); const QVariant value = variantProperty.value(); const QString stringValue = value.toString(); if (property.name() == "id") return stringValue; if (variantProperty.parentModelNode().metaInfo().isValid() && variantProperty.parentModelNode().metaInfo().propertyIsEnumType(variantProperty.name())) { return variantProperty.parentModelNode().metaInfo().propertyEnumScope(variantProperty.name()) + QLatin1String(".") + stringValue; //Enums do not work with alias properties. This is a workaround. } else if (variantProperty.parentModelNode().metaInfo().isValid() //Enums are not strings && variantProperty.parentModelNode().metaInfo().propertyTypeName(variantProperty.name()) != ("string") && variantProperty.parentModelNode().metaInfo().propertyTypeName(variantProperty.name()) != ("QString") //We check if the value of the property is one of the known Qt Quick enums. && NodeMetaInfo::qtQuickEnumsWithoutScope().contains(stringValue) ) { return NodeMetaInfo::qtQuickEnumScopeForEnumString(stringValue) + QLatin1String(".") + stringValue; } else { switch (value.type()) { case QVariant::Bool: if (value.value<bool>()) return QLatin1String("true"); else return QLatin1String("false"); case QVariant::Color: return QString(QLatin1String("\"%1\"")).arg(properColorName(value.value<QColor>())); case QVariant::Double: return doubleToString(value.toDouble()); case QVariant::Int: case QVariant::LongLong: case QVariant::UInt: case QVariant::ULongLong: return stringValue; default: return QString(QLatin1String("\"%1\"")).arg(escape(stringValue)); } } } else { Q_ASSERT("Unknown property type"); return QString(); } }