Merge pull request #5 from status-im/fix/improved-QTBUG-57971-handling

Improve handling of QTBUG-57971 (ListModel initializing roles on first insertion)
This commit is contained in:
Michał 2024-09-16 16:25:52 +02:00 committed by GitHub
commit 984560cfb0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 38 additions and 3 deletions

View File

@ -380,10 +380,45 @@ void QQmlSortFilterProxyModel::resetInternalData()
void QQmlSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
if (sourceModel && sourceModel->roleNames().isEmpty()) { // workaround for when a model has no roles and roles are added when the model is populated (ListModel)
// QTBUG-57971
connect(sourceModel, &QAbstractItemModel::rowsInserted, this, &QQmlSortFilterProxyModel::initRoles);
// QML built-in type ListModel behaves in a specific way regarding roles
// initialization (QTBUG-57971). Empty model has no roles, they become
// available after first insertion. However modelAboutToBeReset/modelReset
// is not emited. It means that roles may change not only in between model
// resets but also on the first insertion.
// In a simple case, where ListModel (or other model behaving in that way)
// is direct source of SFPM, situation is relatively simple - if source
// has no roles, SFPM should try to initialize them on first insertion
// However this behavior has far-reaching consequences, because the
// ListModel-like model may not be a direct source for SFPM. E.g. there may
// by another SFPM in between, with proxy roles defined:
//
// ListModel -> SFPM 1 (with proxy roles) -> SFPM 2
//
// In such scenario SFPM 2 will always have model with roles as it's source
// (at least proxy roles). It means that on first insertion right after
// SFPM creation or after source model reset it's necessary to re-initialize
// role names if the source was empty before insertion.
if (auto currentSource = this->sourceModel()) {
disconnect(currentSource, &QAbstractItemModel::rowsInserted, this,
&QQmlSortFilterProxyModel::initRoles);
disconnect(currentSource, &QAbstractItemModel::modelReset, this, nullptr);
}
if (sourceModel && sourceModel->rowCount() == 0)
connect(sourceModel, &QAbstractItemModel::rowsInserted, this,
&QQmlSortFilterProxyModel::initRoles, Qt::UniqueConnection);
if (sourceModel) {
connect(sourceModel, &QAbstractItemModel::modelReset, this, [sourceModel, this]() {
if (sourceModel->rowCount() != 0)
return;
connect(sourceModel, &QAbstractItemModel::rowsInserted, this,
&QQmlSortFilterProxyModel::initRoles, Qt::UniqueConnection);
});
}
QSortFilterProxyModel::setSourceModel(sourceModel);
}