diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-04-18 15:33:58 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-04-19 20:26:24 +0200 |
commit | 936fe007ee97ebfcab5fda749bcbbf333744ca9e (patch) | |
tree | b44cab581ee9eeccf258c71674c20f9869b6181f | |
parent | 22b0ed0757ac9c73e1f6974fb60d4f2dbc490e3f (diff) |
Fix setting combo data with QSortFilterProxyModel
qtbase/c27d2a57a441f9a1ce760e71635bd4c96882249d caused the code
to go through QStandardItemPrivate::setItemData() which does
not handle the special treatment of Qt::EditRole completely.
In the constructor of QStandardItemData; map Qt::EditRole to
Qt::DisplayRole to fix this as is done in setData().
Adapt the existing tst_QStandardItemModel::getSetItemData() to check
whether both roles are received in the dataChanged() signal.
Pick-to: 6.5
Fixes: QTBUG-112326
Change-Id: I133d058bacc3388c612c5b4fb18b54f5ef5cb56f
Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
Reviewed-by: David Faure <david.faure@kdab.com>
-rw-r--r-- | src/gui/itemmodels/qstandarditemmodel_p.h | 6 | ||||
-rw-r--r-- | tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp | 84 |
2 files changed, 60 insertions, 30 deletions
diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h index def6c20727..f25aa44116 100644 --- a/src/gui/itemmodels/qstandarditemmodel_p.h +++ b/src/gui/itemmodels/qstandarditemmodel_p.h @@ -32,8 +32,10 @@ class QStandardItemData { public: inline QStandardItemData() : role(-1) {} - inline QStandardItemData(int r, const QVariant &v) : role(r), value(v) {} - inline QStandardItemData(const std::pair<const int&, const QVariant&> &p) : role(p.first), value(p.second) {} + inline QStandardItemData(int r, const QVariant &v) : + role(r == Qt::EditRole ? Qt::DisplayRole : r), value(v) {} + inline QStandardItemData(const std::pair<const int&, const QVariant&> &p) : + role(p.first == Qt::EditRole ? Qt::DisplayRole : p.first), value(p.second) {} int role; QVariant value; inline bool operator==(const QStandardItemData &other) const { return role == other.role && value == other.value; } diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp index 07fc074577..73e74b2229 100644 --- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -5,12 +5,17 @@ #include <QTest> #include <QStandardItemModel> #include <QTreeView> +#include <QMap> #include <QSignalSpy> #include <QAbstractItemModelTester> #include <private/qabstractitemmodel_p.h> #include <private/qtreeview_p.h> +#include <algorithm> + +using namespace Qt::StringLiterals; + class tst_QStandardItemModel : public QObject { Q_OBJECT @@ -87,6 +92,7 @@ private slots: void indexFromItem(); void itemFromIndex(); void getSetItemPrototype(); + void getSetItemData_data(); void getSetItemData(); void setHeaderLabels_data(); void setHeaderLabels(); @@ -1025,33 +1031,49 @@ void tst_QStandardItemModel::getSetItemPrototype() QCOMPARE(model.itemPrototype(), nullptr); } +using RoleMap = QMap<int, QVariant>; +using RoleList = QList<int>; + +static RoleMap getSetItemDataRoleMap(int textRole) +{ + return {{textRole, "text"_L1}, + {Qt::StatusTipRole, "statusTip"_L1}, + {Qt::ToolTipRole, "toolTip"_L1}, + {Qt::WhatsThisRole, "whatsThis"_L1}, + {Qt::SizeHintRole, QSize{64, 48}}, + {Qt::FontRole, QFont{}}, + {Qt::TextAlignmentRole, int(Qt::AlignLeft|Qt::AlignVCenter)}, + {Qt::BackgroundRole, QColor(Qt::blue)}, + {Qt::ForegroundRole, QColor(Qt::green)}, + {Qt::CheckStateRole, int(Qt::PartiallyChecked)}, + {Qt::AccessibleTextRole, "accessibleText"_L1}, + {Qt::AccessibleDescriptionRole, "accessibleDescription"_L1}}; +} + +void tst_QStandardItemModel::getSetItemData_data() +{ + QTest::addColumn<RoleMap>("itemData"); + QTest::addColumn<RoleMap>("expectedItemData"); + QTest::addColumn<RoleList>("expectedRoles"); + + // QTBUG-112326: verify that text data set using Qt::EditRole is mapped to + // Qt::DisplayRole and both roles are in the changed signal + const RoleMap expectedItemData = getSetItemDataRoleMap(Qt::DisplayRole); + RoleList expectedRoles = expectedItemData.keys() << Qt::EditRole; + std::sort(expectedRoles.begin(), expectedRoles.end()); + + QTest::newRow("DisplayRole") << expectedItemData + << expectedItemData << expectedRoles; + + QTest::newRow("EditRole") << getSetItemDataRoleMap(Qt::EditRole) + << expectedItemData << expectedRoles; +} + void tst_QStandardItemModel::getSetItemData() { - QMap<int, QVariant> roles; - QLatin1String text("text"); - roles.insert(Qt::DisplayRole, text); - QLatin1String statusTip("statusTip"); - roles.insert(Qt::StatusTipRole, statusTip); - QLatin1String toolTip("toolTip"); - roles.insert(Qt::ToolTipRole, toolTip); - QLatin1String whatsThis("whatsThis"); - roles.insert(Qt::WhatsThisRole, whatsThis); - QSize sizeHint(64, 48); - roles.insert(Qt::SizeHintRole, sizeHint); - QFont font; - roles.insert(Qt::FontRole, font); - Qt::Alignment textAlignment(Qt::AlignLeft|Qt::AlignVCenter); - roles.insert(Qt::TextAlignmentRole, int(textAlignment)); - QColor backgroundColor(Qt::blue); - roles.insert(Qt::BackgroundRole, backgroundColor); - QColor textColor(Qt::green); - roles.insert(Qt::ForegroundRole, textColor); - Qt::CheckState checkState(Qt::PartiallyChecked); - roles.insert(Qt::CheckStateRole, int(checkState)); - QLatin1String accessibleText("accessibleText"); - roles.insert(Qt::AccessibleTextRole, accessibleText); - QLatin1String accessibleDescription("accessibleDescription"); - roles.insert(Qt::AccessibleDescriptionRole, accessibleDescription); + QFETCH(RoleMap, itemData); + QFETCH(RoleMap, expectedItemData); + QFETCH(RoleList, expectedRoles); QStandardItemModel model; model.insertRows(0, 1); @@ -1060,11 +1082,17 @@ void tst_QStandardItemModel::getSetItemData() QSignalSpy modelDataChangedSpy( &model, &QStandardItemModel::dataChanged); - QVERIFY(model.setItemData(idx, roles)); + QVERIFY(model.setItemData(idx, itemData)); QCOMPARE(modelDataChangedSpy.size(), 1); - QVERIFY(model.setItemData(idx, roles)); + const QVariantList &args = modelDataChangedSpy.constFirst(); + QCOMPARE(args.size(), 3); + auto roleList = args.at(2).value<QList<int> >(); + std::sort(roleList.begin(), roleList.end()); + QCOMPARE(roleList, expectedRoles); + + QVERIFY(model.setItemData(idx, itemData)); QCOMPARE(modelDataChangedSpy.size(), 1); //it was already changed once - QCOMPARE(model.itemData(idx), roles); + QCOMPARE(model.itemData(idx), expectedItemData); } void tst_QStandardItemModel::setHeaderLabels_data() |