QmlDesigner.NodeInstances: Fixing enums for int properties

There is no easy way to convert an enum (e.g. Qt.Vertical) to the
integer value without the meta object/QMetaEnum.

For this reason we evluate the enum as an expression
if the target property is int.

Without this patch enums do not work at all for properties defined as int.
Change-Id: I9363a84eef1bf4a3ed2c40b35f7439e249e9bd98
Reviewed-by: Tim Jenssen <tim.jenssen@digia.com>
This commit is contained in:
Thomas Hartmann
2014-08-21 13:34:22 +02:00
parent 1a690d4b95
commit b6e6e0123c
2 changed files with 34 additions and 42 deletions
@@ -53,6 +53,7 @@
#include <private/qquickanimation_p.h>
#include <private/qqmltimer_p.h>
#include <private/qqmlengine_p.h>
#include <private/qqmlexpression_p.h>
#include <designersupport.h>
@@ -102,8 +103,6 @@ static bool isSimpleExpression(const QString &expression)
namespace QmlDesigner {
namespace Internal {
QHash<EnumerationName, QVariant> ObjectNodeInstance::m_enumationValueHash;
ObjectNodeInstance::ObjectNodeInstance(QObject *object)
: m_object(object),
m_metaObject(0),
@@ -474,6 +473,37 @@ PropertyNameList ObjectNodeInstance::ignoredProperties() const
return PropertyNameList();
}
QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name)
{
int idx = object()->metaObject()->indexOfProperty(name);
QMetaProperty metaProperty = object()->metaObject()->property(idx);
QVariant fixedValue = fixResourcePaths(value);
if (value.canConvert<Enumeration>()) {
Enumeration enumeration = value.value<Enumeration>();
if (metaProperty.isValid() && metaProperty.isEnumType()) {
fixedValue = metaProperty.enumerator().keyToValue(enumeration.name());
} else if (metaProperty.isValid()
&& (QLatin1String(metaProperty.typeName()) == QLatin1String("int"))) {
//If the target property is an integer handle an enum as binding
QQmlExpression expression(context(), object(), enumeration.toString());
fixedValue = expression.evaluate();
if (expression.hasError())
qDebug() << "Enum can not be evaluated:" << object() << name << enumeration;
} else if (!metaProperty.isValid()) { //In this case this is most likely an attached property
QQmlExpression expression(context(), object(), enumeration.toString());
fixedValue = expression.evaluate();
if (expression.hasError())
qDebug() << "Enum can not be evaluated:" << object() << name << enumeration;
}
}
return fixedValue;
}
void ObjectNodeInstance::setPropertyVariant(const PropertyName &name, const QVariant &value)
{
if (ignoredProperties().contains(name))
@@ -485,9 +515,7 @@ void ObjectNodeInstance::setPropertyVariant(const PropertyName &name, const QVar
return;
QVariant fixedValue = fixResourcePaths(value);
if (value.canConvert<Enumeration>())
fixedValue = enumationValue(value.value<Enumeration>());
fixedValue = convertEnumToValue(fixedValue, name);
QVariant oldValue = property.read();
if (oldValue.type() == QVariant::Url) {
@@ -1342,43 +1370,6 @@ void ObjectNodeInstance::doComponentCompleteRecursive(QObject *object, NodeInsta
}
}
static QHash<EnumerationName, QVariant> enumationValuesFromMetaEnum(const QMetaEnum &metaEnum)
{
QHash<EnumerationName, QVariant> enumationValues;
for (int index = 0; index < metaEnum.keyCount(); index++) {
EnumerationName enumerationName = EnumerationName(metaEnum.scope()) + "." + metaEnum.key(index);
enumationValues.insert(enumerationName, QVariant::fromValue(metaEnum.value(index)));
qDebug() << __FUNCTION__ << enumerationName << metaEnum.value(index);
}
return enumationValues;
}
static QHash<EnumerationName, QVariant> collectEnumationValues(const Enumeration &enumeration)
{
QHash<EnumerationName, QVariant> enumationValues;
EnumerationName enumerationScope = enumeration.scope();
const QMetaObject *metaObject = QMetaType::metaObjectForType(QMetaType::type(enumerationScope.constData()));
if (metaObject) {
int enumeratorCount = metaObject->enumeratorOffset() + metaObject->enumeratorCount();
for (int index = metaObject->enumeratorOffset(); index < enumeratorCount; index++)
enumationValues.unite(enumationValuesFromMetaEnum(metaObject->enumerator(index)));
} else {
enumationValues.insert(enumeration.toEnumerationName(), QVariant::fromValue(enumeration.nameToString()));
}
return enumationValues;
}
QVariant ObjectNodeInstance::enumationValue(const Enumeration &enumeration)
{
EnumerationName enumerationName = enumeration.toEnumerationName();
if (!m_enumationValueHash.contains(enumerationName))
m_enumationValueHash.unite(collectEnumationValues(enumeration));
return m_enumationValueHash.value(enumerationName);
}
ObjectNodeInstance::Pointer ObjectNodeInstance::parentInstance() const
{
QObject *parentHolder = parent();
@@ -200,6 +200,7 @@ protected:
void addToNewProperty(QObject *object, QObject *newParent, const PropertyName &newParentProperty);
void deleteObjectsInList(const QQmlProperty &metaProperty);
QVariant convertSpecialCharacter(const QVariant& value) const;
QVariant convertEnumToValue(const QVariant &value, const PropertyName &name);
static QObject *parentObject(QObject *object);
static void doComponentCompleteRecursive(QObject *object, NodeInstanceServer *nodeInstanceServer);
static QVariant enumationValue(const Enumeration &enumeration);