diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-03-21 14:13:26 +0100 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-03-23 23:06:23 +0100 |
commit | 6880b7c39b2c7474be1c9adcabbe0b7d6596822f (patch) | |
tree | 2ad5298062452dfdd3d87a07355ea003e46edddf /src/corelib/itemmodels | |
parent | af875e88f46a2947c313bd724ab9b10f3e7268df (diff) |
Itemviews: start fixing mixups of int/enum for Qt's item roles
A model is supposed to return a Qt::CheckState for a CheckStateRole,
and a Qt::Alignment for a Qt::TextAlignmentRole. This is what the
documentation says (and what makes sense), but unfortunately
Qt's default delegate expected a plain `int` instead.
This sometimes worked (via QVariant conversions, e.g. when using a plain
enum) and sometimes didn't (e.g. when using a flag type).
This is confusing for end-users (and type unsafe, killing the whole
point of using enums and flags in the first place).
Adding some automatic flags<->int conversions through QVariant is
frowned upon, so I don't want to go there. Instead, add some private
convenience functions that extract either the right type from a variant,
or try to extract an `int` and convert it to the expected type.
Use these from within itemviews code.
Change-Id: I44bee98c4a26a1ef6c3b2fa1b8de2edfee7aef32
Pick-to: 6.2 6.3
Fixes: QTBUG-75172
Task-number: QTBUG-74639
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/itemmodels')
-rw-r--r-- | src/corelib/itemmodels/qabstractitemmodel_p.h | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index e8f00975ed..edc5ad6116 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -157,6 +157,52 @@ public: }; Q_DECLARE_TYPEINFO(QAbstractItemModelPrivate::Change, Q_RELOCATABLE_TYPE); +namespace QtPrivate { + +/*! + \internal + This is a workaround for QTBUG-75172. + + Some predefined model roles are supposed to use certain enum/flag + types (e.g. fetching Qt::TextAlignmentRole is supposed to return a + variant containing a Qt::Alignment object). + + For historical reasons, a plain `int` was used sometimes. This is + surprising to end-users and also sloppy on Qt's part; users were + forced to use `int` rather than the correct datatype. + + This function tries both the "right" type and plain `int`, for a + given QVariant. This fixes the problem (using the correct datatype) + but also keeps compatibility with existing code using `int`. + + ### Qt 7: get rid of this. Always use the correct datatype. +*/ +template <typename T> +T legacyEnumValueFromModelData(const QVariant &data) +{ + static_assert(std::is_enum_v<T>); + if (data.userType() == qMetaTypeId<T>()) + return data.value<T>(); + else if (data.userType() == qMetaTypeId<int>()) + return T(data.toInt()); + + return T(); +} + +template <typename T> +T legacyFlagValueFromModelData(const QVariant &data) +{ + if (data.userType() == qMetaTypeId<T>()) + return data.value<T>(); + else if (data.userType() == qMetaTypeId<int>()) + return T::fromInt(data.toInt()); + + return T(); +} + +} // namespace QtPrivate + + QT_END_NAMESPACE #endif // QABSTRACTITEMMODEL_P_H |