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>
This commit is contained in:
Thomas Hartmann
2013-10-16 15:23:30 +02:00
committed by Marco Bubke
parent 7f09973ca2
commit a6d6db3397
4 changed files with 133 additions and 5 deletions

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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()) {

View File

@@ -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();