aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUnai IRIGOYEN <u.irigoyen@gmail.com>2019-11-04 21:45:29 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-08-22 22:44:32 +0200
commit1876bd4215ccf5bbaa6f571177db889ba4bc8eff (patch)
treec0f6305b305119d7c509f1ef4cee908f62b689f3 /src/qml
parent3d195d33ece3f8fd7cd7d8e6163fe038fc7fc036 (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/qml')
-rw-r--r--src/qml/qml/qqmllist.cpp77
-rw-r--r--src/qml/qml/qqmllist.h4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp29
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>();