summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorIevgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>2021-09-21 11:32:01 +0200
committerIevgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>2021-10-20 17:04:51 +0200
commitaf2f88f5b65d597116140f661030ba1ccf560ab2 (patch)
tree3c6c3bd30c5e04231b64a039d59600104b4365de /src/corelib/kernel
parentbb8d84c358eb4b324258b936bdeb211fdd90d7cd (diff)
QObjectCompatProperty: Add support for custom getters
Add additional template argument to QObjectCompatProperty to specify a custom getter. This may be useful for classes like QAbstractProxyModelPrivate the need to customize property getters. Task-number: QTBUG-89655 Change-Id: I34fe4bdebbbf1446aff60bd20a946454607f52d5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qproperty.h2
-rw-r--r--src/corelib/kernel/qproperty_p.h36
-rw-r--r--src/corelib/kernel/qpropertyprivate.h4
3 files changed, 31 insertions, 11 deletions
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 4358182c25..f653d78fb6 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -956,7 +956,7 @@ class Q_CORE_EXPORT QBindingStorage
mutable QBindingStorageData *d = nullptr;
QBindingStatus *bindingStatus = nullptr;
- template<typename Class, typename T, auto Offset, auto Setter, auto Signal>
+ template<typename Class, typename T, auto Offset, auto Setter, auto Signal, auto Getter>
friend class QObjectCompatProperty;
friend class QObjectPrivate;
friend class QtPrivate::QPropertyBindingData;
diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h
index 0e01026d54..cc080ff82b 100644
--- a/src/corelib/kernel/qproperty_p.h
+++ b/src/corelib/kernel/qproperty_p.h
@@ -447,13 +447,14 @@ namespace QtPrivate {
void Q_CORE_EXPORT initBindingStatusThreadId();
}
-template<typename Class, typename T, auto Offset, auto Setter, auto Signal=nullptr>
+template<typename Class, typename T, auto Offset, auto Setter, auto Signal = nullptr,
+ auto Getter = nullptr>
class QObjectCompatProperty : public QPropertyData<T>
{
template<typename Property, typename>
friend class QtPrivate::QBindableInterfaceForProperty;
- using ThisType = QObjectCompatProperty<Class, T, Offset, Setter, Signal>;
+ using ThisType = QObjectCompatProperty<Class, T, Offset, Setter, Signal, Getter>;
using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
Class *owner()
{
@@ -486,6 +487,14 @@ class QObjectCompatProperty : public QPropertyData<T>
&& QtPrivate::isPropertyInBindingWrapper(this);
}
+ inline static T getPropertyValue(const QUntypedPropertyData *d) {
+ auto prop = static_cast<const ThisType *>(d);
+ if constexpr (std::is_null_pointer_v<decltype(Getter)>)
+ return prop->value();
+ else
+ return (prop->owner()->*Getter)();
+ }
+
public:
using value_type = typename QPropertyData<T>::value_type;
using parameter_type = typename QPropertyData<T>::parameter_type;
@@ -596,7 +605,7 @@ public:
}
if constexpr (!std::is_null_pointer_v<decltype(Signal)>) {
if constexpr (SignalTakesValue::value)
- (owner()->*Signal)(value());
+ (owner()->*Signal)(getPropertyValue(this));
else
(owner()->*Signal)();
}
@@ -650,15 +659,16 @@ private:
};
namespace QtPrivate {
-template<typename Class, typename Ty, auto Offset, auto Setter, auto Signal>
-class QBindableInterfaceForProperty<QObjectCompatProperty<Class, Ty, Offset, Setter, Signal>, std::void_t<Class>>
+template<typename Class, typename Ty, auto Offset, auto Setter, auto Signal, auto Getter>
+class QBindableInterfaceForProperty<
+ QObjectCompatProperty<Class, Ty, Offset, Setter, Signal, Getter>, std::void_t<Class>>
{
- using Property = QObjectCompatProperty<Class, Ty, Offset, Setter, Signal>;
+ using Property = QObjectCompatProperty<Class, Ty, Offset, Setter, Signal, Getter>;
using T = typename Property::value_type;
public:
static constexpr QBindableInterface iface = {
[](const QUntypedPropertyData *d, void *value) -> void
- { *static_cast<T*>(value) = static_cast<const Property *>(d)->value(); },
+ { *static_cast<T*>(value) = Property::getPropertyValue(d); },
[](QUntypedPropertyData *d, const void *value) -> void
{
(static_cast<Property *>(d)->owner()->*Setter)(*static_cast<const T*>(value));
@@ -668,7 +678,7 @@ public:
[](QUntypedPropertyData *d, const QUntypedPropertyBinding &binding) -> QUntypedPropertyBinding
{ return static_cast<Property *>(d)->setBinding(static_cast<const QPropertyBinding<T> &>(binding)); },
[](const QUntypedPropertyData *d, const QPropertyBindingSourceLocation &location) -> QUntypedPropertyBinding
- { return Qt::makePropertyBinding([d]() -> T { return static_cast<const Property *>(d)->value(); }, location); },
+ { return Qt::makePropertyBinding([d]() -> T { return Property::getPropertyValue(d); }, location); },
[](const QUntypedPropertyData *d, QPropertyObserver *observer) -> void
{ observer->setSource(static_cast<const Property *>(d)->bindingData()); },
[]() { return QMetaType::fromType<T>(); }
@@ -717,6 +727,16 @@ public:
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, \
signal>(value);
+#define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_7(Class, Type, name, setter, signal, getter, value) \
+ static constexpr size_t _qt_property_##name##_offset() { \
+ QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
+ return offsetof(Class, name); \
+ QT_WARNING_POP \
+ } \
+ QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal, getter>\
+ name = QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, \
+ signal, getter>(value);
+
#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(...) \
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
QT_OVERLOADED_MACRO(QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS, __VA_ARGS__) \
diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h
index d3f384748a..fec69f3a72 100644
--- a/src/corelib/kernel/qpropertyprivate.h
+++ b/src/corelib/kernel/qpropertyprivate.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QBindingStorage;
-template<typename Class, typename T, auto Offset, auto Setter, auto Signal>
+template<typename Class, typename T, auto Offset, auto Setter, auto Signal, auto Getter>
class QObjectCompatProperty;
namespace QtPrivate {
@@ -263,7 +263,7 @@ class Q_CORE_EXPORT QPropertyBindingData
friend class QT_PREPEND_NAMESPACE(QQmlPropertyBinding);
friend struct QT_PREPEND_NAMESPACE(QPropertyDelayedNotifications);
- template<typename Class, typename T, auto Offset, auto Setter, auto Signal>
+ template<typename Class, typename T, auto Offset, auto Setter, auto Signal, auto Getter>
friend class QT_PREPEND_NAMESPACE(QObjectCompatProperty);
Q_DISABLE_COPY(QPropertyBindingData)