Skip to content

Commit

Permalink
Merge pull request #5 from status-im/fix/improved-QTBUG-57971-handling
Browse files Browse the repository at this point in the history
Improve handling of QTBUG-57971 (ListModel initializing roles on first insertion)
  • Loading branch information
micieslak authored Sep 16, 2024
2 parents b176bad + 40daec0 commit 984560c
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions qqmlsortfilterproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down

0 comments on commit 984560c

Please sign in to comment.