From a1e9817cec5e0dccf26040d0b0d24e974841d5b8 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 13 Dec 2020 21:37:23 +0100 Subject: QStandardItem(Model): refactor multiData support QSI(M) allow users to override their data() functions. This means that we can't have their data() implemented in terms of multiData(), or otherwise a subclass that overrides data() will fall out of sync with its multiData() implementation. We must keep multiData() implemented in terms of data() instead. While at it, document QSI::multiData(). Pick-to: 6.0 6.1 Task-number: QTBUG-89423 Change-Id: If30a980d8449135b516745fec73170d53367b4b7 Reviewed-by: Christian Ehrlicher --- src/gui/itemmodels/qstandarditemmodel.cpp | 47 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'src/gui/itemmodels/qstandarditemmodel.cpp') diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 8ae5a3bf6c..a972b7b106 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -966,31 +966,29 @@ void QStandardItem::clearData() */ QVariant QStandardItem::data(int role) const { - QModelRoleData result(role); - multiData(result); - return result.data(); + Q_D(const QStandardItem); + const int r = (role == Qt::EditRole) ? Qt::DisplayRole : role; + for (const auto &value : d->values) { + if (value.role == r) + return value.value; + } + return QVariant(); } -void QStandardItem::multiData(QModelRoleDataSpan roleDataSpan) const -{ - Q_D(const QStandardItem); +/*! + \since 6.0 - const auto valuesBegin = d->values.begin(); - const auto valuesEnd = d->values.end(); + Fills the \a roleDataSpan span with the data from this item. - for (auto &roleData : roleDataSpan) { - const int role = (roleData.role() == Qt::EditRole) ? Qt::DisplayRole : roleData.role(); - const auto hasSameRole = [role](const QStandardItemData &data) - { - return data.role == role; - }; + The default implementation simply calls data() for each role + in the span. - auto dataIt = std::find_if(valuesBegin, valuesEnd, hasSameRole); - if (dataIt != valuesEnd) - roleData.setData(dataIt->value); - else - roleData.clearData(); - } + \sa data() +*/ +void QStandardItem::multiData(QModelRoleDataSpan roleDataSpan) const +{ + for (auto &roleData : roleDataSpan) + roleData.setData(data(roleData.role())); } /*! @@ -2850,10 +2848,11 @@ QVariant QStandardItemModel::data(const QModelIndex &index, int role) const */ void QStandardItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const { - Q_D(const QStandardItemModel); - QStandardItem *item = d->itemFromIndex(index); - if (item) - item->multiData(roleDataSpan); + // Cannot offer a better implementation; users may be overriding + // data(), and thus multiData() may fall out of sync for them. + // The base class' implementation will simply call data() in a loop, + // so it's fine. + QAbstractItemModel::multiData(index, roleDataSpan); } /*! -- cgit v1.2.3