diff options
author | Thomas Hartmann <Thomas.Hartmann@digia.com> | 2013-10-16 15:23:30 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@digia.com> | 2013-10-16 16:13:00 +0200 |
commit | a6d6db3397b82dc9fca5517c3ad2595f00c89f90 (patch) | |
tree | 3b96ad3ff755bd00cd4312e922fb9f22aeab0f5f | |
parent | 7f09973ca219e4db9a9f320cb31f3294e6a2e80e (diff) |
QmlDesigner: Support for enums in alias properties
Enums in combination with alias properties were not supported.
The QML Engine does not distinguish between bindings
and enums in this case.
We want to distinguish between bindings/expressions and literal
enums. This is not possible with the current code model, so we use
a list of hardcoded enum keys for Qt Quick.
There a several issues we want to properly fix in the future.
* Make the model aware of enums. Currently enums are strings
(the key) in the model. This has historical reasons. Instead
we should use a custom type registered to QVariant that handles
the scope, key and integer value.
* The code model should be fully aware of enums even in the alias case.
Do not integrate this patch to 3.0 or master.
Task-number: QTCREATORBUG-10114
Change-Id: I780a201202f0949b1e2eb2f2525ddb031e1cd18b
Reviewed-by: Marco Bubke <marco.bubke@digia.com>
4 files changed, 133 insertions, 5 deletions
diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h index c06b72a212..46e638f54c 100644 --- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h @@ -104,6 +104,11 @@ public: static void clearCache(); + //### TODO: These are hardcoded and ideally the code model should be able to provide them + static QStringList qtQuickEnums(); + static QStringList qtQuickEnumsWithoutScope(); + static QString qtQuickEnumScopeForEnumString(const QString &inputEnumString); + private: QSharedPointer<Internal::NodeMetaInfoPrivate> m_privateData; }; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index a10bfdd988..750f9a3624 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -1307,4 +1307,108 @@ bool NodeMetaInfo::isLayoutable() const return isSubclassOf("QtQuick.Positioner", -1, -1) || isSubclassOf("QtQuick.Layouts.Layout", -1, -1); } +QStringList NodeMetaInfo::qtQuickEnums() +{ + static QStringList stringList = QStringList() + +/* Font*/ + + << QLatin1String("Font.Light") + << QLatin1String("Font.Normal") + << QLatin1String("Font.DemiBold") + << QLatin1String("Font.Bold") + << QLatin1String("Font.Black") + +/* Text*/ + + << QLatin1String("Text.AutoText") + << QLatin1String("Text.PlainText") + << QLatin1String("Text.RichText") + << QLatin1String("Text.StyledText") + + << QLatin1String("Text.Normal") + << QLatin1String("Text.Outline") + << QLatin1String("Text.Raised") + << QLatin1String("Text.Sunken") + + << QLatin1String("Text.AlignLeft") + << QLatin1String("Text.AlignRight") + << QLatin1String("Text.AlignHCenter") + << QLatin1String("Text.AlignJustify") + + << QLatin1String("Text.AlignTop") + << QLatin1String("Text.AlignBottom") + << QLatin1String("Text.AlignVCenter") + + << QLatin1String("Text.QtRendering") + << QLatin1String("Text.NativeRendering") + + << QLatin1String("Text.NoWrap") + << QLatin1String("Text.WordWrap") + << QLatin1String("Text.WrapAnywhere") + << QLatin1String("Text.Wrap") + +/* Flickable */ + + << QLatin1String("Flickable.StopAtBounds") + << QLatin1String("Flickable.DragOverBounds") + << QLatin1String("Flickable.DragAndOvershootBounds") + + << QLatin1String("Flickable.AutoFlickDirection") + << QLatin1String("Flickable.HorizontalFlick") + << QLatin1String("Flickable.VerticalFlick") + << QLatin1String("Flickable.HorizontalAndVerticalFlick") + +/* Grid */ + + << QLatin1String("Grid.LeftToRight") + << QLatin1String("Grid.TopToBottom") + +/* Flow */ + + << QLatin1String("Flow.LeftToRight") + << QLatin1String("Flow.TopToBottom") + +/* GridView */ + + << QLatin1String("GridView.NoSnap") + << QLatin1String("GridView.SnapToRow") + << QLatin1String("GridView.SnapOneRow"); + + return stringList; +} + +static inline QStringList removeScope(QStringList enumList) +{ + QStringList stringList; + + foreach (const QString &enumString, enumList) { + QStringList splittedString = enumString.split(QLatin1String(".")); + Q_ASSERT(splittedString.count() == 2); + stringList.append(splittedString.last()); + } + + return stringList; +} + +QStringList NodeMetaInfo::qtQuickEnumsWithoutScope() +{ + static QStringList stringList = removeScope(qtQuickEnums()); + return stringList; +} + +QString NodeMetaInfo::qtQuickEnumScopeForEnumString(const QString &inputEnumString) +{ + if (qtQuickEnumsWithoutScope().contains(inputEnumString)) { + foreach (const QString &enumString, qtQuickEnums()) { + QStringList splittedString = enumString.split(QLatin1String(".")); + Q_ASSERT(splittedString.count() == 2); + if (splittedString.last() == inputEnumString) + return splittedString.first(); + } + } + + return QString(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp index 4fa4a8b82b..467870a579 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp @@ -111,11 +111,21 @@ QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDept if (property.name() == "id") return stringValue; - if (false) { - } - if (variantProperty.parentModelNode().metaInfo().isValid() && - variantProperty.parentModelNode().metaInfo().propertyIsEnumType(variantProperty.name())) { - return variantProperty.parentModelNode().metaInfo().propertyEnumScope(variantProperty.name()) + '.' + 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()) { diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 8948278ec2..3d9ab7b8f9 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -549,6 +549,10 @@ public: value.convert(QVariant::Bool); return value; } else if (property->asNumberValue()) { + //Enums in alias properties pretend to be a number. + //In Qt Quick 1 this was still valid syntax. + if (NodeMetaInfo::qtQuickEnumsWithoutScope().contains(value.toString())) + return value.toString(); value.convert(QVariant::Double); return value; } else if (property->asStringValue()) { @@ -569,6 +573,11 @@ public: && globalQtEnums().contains(astValueList.last())) return QVariant(astValueList.last()); + if (astValueList.count() == 2 //Check for global Qt Quick enums + && NodeMetaInfo::qtQuickEnums().contains(astValue)) { + return QVariant(astValueList.last()); + } + ExpressionStatement *eStmt = cast<ExpressionStatement *>(rhs); if (!eStmt || !eStmt->expression) return QVariant(); |