diff options
author | Unai IRIGOYEN <u.irigoyen@gmail.com> | 2019-11-04 21:45:29 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-08-22 22:44:32 +0200 |
commit | 1876bd4215ccf5bbaa6f571177db889ba4bc8eff (patch) | |
tree | c0f6305b305119d7c509f1ef4cee908f62b689f3 /src | |
parent | 3d195d33ece3f8fd7cd7d8e6163fe038fc7fc036 (diff) |
Add override behaviors to QQmlListProperty
[ChangeLog][QQmlListProperty] When overriding a
QQmlListProperty in a derived QML type, the default behavior is to
append the derived class elements to the base class ones. This
introduces a macro to allow replacing the base
type contents either always or if the property is not the default one.
Fixes: QTBUG-77529
Change-Id: Ib1abbf52e341c043344c347c612928b47856fb3e
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmllist.cpp | 77 | ||||
-rw-r--r-- | src/qml/qml/qqmllist.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 29 |
3 files changed, 110 insertions, 0 deletions
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp index 717170d362..a0d34cbce7 100644 --- a/src/qml/qml/qqmllist.cpp +++ b/src/qml/qml/qqmllist.cpp @@ -429,6 +429,83 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th */ /*! + \macro QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND + \relates QQmlListProperty + + This macro defines the behavior of the list properties of this class to Append. + When assigning the property in a derived type, the values are appended + to those of the base class. This is the default behavior. + + \code + class FruitBasket : QObject { + \Q_OBJECT + QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND + Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit) + + public: + // ... + QQmlListProperty<Fruit> fruit(); + // ... + }; + \endcode + + \sa QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT + \sa QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE +*/ + +/*! + \macro QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT + \relates QQmlListProperty + + This macro defines the behavior of the list properties of this class to + ReplaceIfNotDefault. + When assigning the property in a derived type, the values replace those of + the base class unless it's the default property. + In the case of the default property, values are appended to those of the base class. + + \code + class FruitBasket : QObject { + \Q_OBJECT + QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT + Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit) + + public: + // ... + QQmlListProperty<Fruit> fruit(); + // ... + }; + \endcode + + \sa QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND + \sa QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE +*/ + +/*! + \macro QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE + \relates QQmlListProperty + + This macro defines the behavior of the list properties of this class to Replace. + When assigning the property in a derived type, the values replace those + of the base class. + + \code + class FruitBasket : QObject { + \Q_OBJECT + QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE + Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit) + + public: + // ... + QQmlListProperty<Fruit> fruit(); + // ... + }; + \endcode + + \sa QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND + \sa QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT +*/ + +/*! \fn template<typename T> QQmlListProperty<T>::QQmlListProperty() \internal */ diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h index 313d7449fe..199f10196a 100644 --- a/src/qml/qml/qqmllist.h +++ b/src/qml/qml/qqmllist.h @@ -50,6 +50,10 @@ QT_BEGIN_NAMESPACE class QObject; struct QMetaObject; +#define QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND Q_CLASSINFO("QML.ListPropertyAssignBehavior", "Append") +#define QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT Q_CLASSINFO("QML.ListPropertyAssignBehavior", "ReplaceIfNotDefault") +#define QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE Q_CLASSINFO("QML.ListPropertyAssignBehavior", "Replace") + #ifndef QQMLLISTPROPERTY #define QQMLLISTPROPERTY template<typename T> diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 5fa0eb281e..11d3dd7b5d 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -782,6 +782,35 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings) void *argv[1] = { (void*)&_currentList }; QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property->coreIndex(), argv); currentListPropertyIndex = property->coreIndex(); + + // manage override behavior + const QMetaObject *const metaobject = _qobject->metaObject(); + const int qmlListBehavorClassInfoIndex = metaobject->indexOfClassInfo("QML.ListPropertyAssignBehavior"); + if (qmlListBehavorClassInfoIndex != -1) { // QML.ListPropertyAssignBehavior class info is set + const char *overrideBehavior = + metaobject->classInfo(qmlListBehavorClassInfoIndex).value(); + if (!strcmp(overrideBehavior, + "Replace")) { + if (_currentList.clear) { + _currentList.clear(&_currentList); + } + } else { + bool isDefaultProperty = + (property->name(_qobject) + == QString::fromUtf8( + metaobject + ->classInfo(metaobject->indexOfClassInfo( + "DefaultProperty")) + .value())); + if (!isDefaultProperty + && (!strcmp(overrideBehavior, + "ReplaceIfNotDefault"))) { + if (_currentList.clear) { + _currentList.clear(&_currentList); + } + } + } + } } } else if (_currentList.object) { _currentList = QQmlListProperty<void>(); |