summaryrefslogtreecommitdiffstats
path: root/src/corelib/itemmodels
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2022-03-21 14:13:26 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2022-03-23 23:06:23 +0100
commit6880b7c39b2c7474be1c9adcabbe0b7d6596822f (patch)
tree2ad5298062452dfdd3d87a07355ea003e46edddf /src/corelib/itemmodels
parentaf875e88f46a2947c313bd724ab9b10f3e7268df (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.h46
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