diff --git a/qqmlsortfilterproxymodel.cpp b/qqmlsortfilterproxymodel.cpp index acc7b9a..2004629 100644 --- a/qqmlsortfilterproxymodel.cpp +++ b/qqmlsortfilterproxymodel.cpp @@ -198,10 +198,10 @@ QQmlListProperty QQmlSortFilterProxyModel::sorters() QQmlListProperty QQmlSortFilterProxyModel::proxyRoles() { return QQmlListProperty(this, &m_proxyRoles, - &QQmlSortFilterProxyModel::append_proxyRole, - &QQmlSortFilterProxyModel::count_proxyRole, - &QQmlSortFilterProxyModel::at_proxyRole, - &QQmlSortFilterProxyModel::clear_proxyRoles); + &QQmlSortFilterProxyModel::append_proxyRole, + &QQmlSortFilterProxyModel::count_proxyRole, + &QQmlSortFilterProxyModel::at_proxyRole, + &QQmlSortFilterProxyModel::clear_proxyRoles); } void QQmlSortFilterProxyModel::classBegin() @@ -245,7 +245,7 @@ QVariant QQmlSortFilterProxyModel::data(const QModelIndex &index, int role) cons QHash QQmlSortFilterProxyModel::roleNames() const { - return m_roleNames; + return m_roleNames.isEmpty() && sourceModel() ? sourceModel()->roleNames() : m_roleNames; } /*! @@ -257,7 +257,7 @@ QHash QQmlSortFilterProxyModel::roleNames() const int QQmlSortFilterProxyModel::roleForName(const QString& roleName) const { - return roleNames().key(roleName.toUtf8(), -1); + return m_roleNames.key(roleName.toUtf8(), -1); } /*! @@ -373,24 +373,16 @@ bool QQmlSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QM void QQmlSortFilterProxyModel::resetInternalData() { QSortFilterProxyModel::resetInternalData(); - if (sourceModel() && QSortFilterProxyModel::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); - connect(this, &QAbstractItemModel::rowsAboutToBeInserted, this, &QQmlSortFilterProxyModel::initRoles); - } - m_roleNames = QSortFilterProxyModel::roleNames(); - m_proxyRoleMap.clear(); - m_proxyRoleNumbers.clear(); + updateRoleNames(); +} - auto roles = m_roleNames.keys(); - auto maxIt = std::max_element(roles.cbegin(), roles.cend()); - int maxRole = maxIt != roles.cend() ? *maxIt : -1; - for (auto proxyRole : m_proxyRoles) { - ++maxRole; - m_roleNames[maxRole] = proxyRole->name().toUtf8(); - m_proxyRoleMap[maxRole] = proxyRole; - m_proxyRoleNumbers.append(maxRole); +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); } + QSortFilterProxyModel::setSourceModel(sourceModel); } void QQmlSortFilterProxyModel::invalidateFilter() @@ -405,6 +397,25 @@ void QQmlSortFilterProxyModel::invalidate() QSortFilterProxyModel::invalidate(); } +void QQmlSortFilterProxyModel::updateRoleNames() +{ + if (!sourceModel()) + return; + m_roleNames = sourceModel()->roleNames(); + m_proxyRoleMap.clear(); + m_proxyRoleNumbers.clear(); + + auto roles = m_roleNames.keys(); + auto maxIt = std::max_element(roles.cbegin(), roles.cend()); + int maxRole = maxIt != roles.cend() ? *maxIt : -1; + for (auto proxyRole : m_proxyRoles) { + ++maxRole; + m_roleNames[maxRole] = proxyRole->name().toUtf8(); + m_proxyRoleMap[maxRole] = proxyRole; + m_proxyRoleNumbers.append(maxRole); + } +} + void QQmlSortFilterProxyModel::updateFilterRole() { QList filterRoles = roleNames().keys(m_filterRoleName.toUtf8()); @@ -433,7 +444,6 @@ void QQmlSortFilterProxyModel::updateRoles() void QQmlSortFilterProxyModel::initRoles() { disconnect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &QQmlSortFilterProxyModel::initRoles); - disconnect(this, &QAbstractItemModel::rowsAboutToBeInserted, this , &QQmlSortFilterProxyModel::initRoles); resetInternalData(); updateRoles(); } diff --git a/qqmlsortfilterproxymodel.h b/qqmlsortfilterproxymodel.h index bc22566..accf21d 100644 --- a/qqmlsortfilterproxymodel.h +++ b/qqmlsortfilterproxymodel.h @@ -85,6 +85,8 @@ public: Q_INVOKABLE QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override; Q_INVOKABLE int mapFromSource(int sourceRow) const; + void setSourceModel(QAbstractItemModel *sourceModel) override; + Q_SIGNALS: void countChanged(); @@ -106,6 +108,7 @@ protected Q_SLOTS: private Q_SLOTS: void invalidateFilter(); void invalidate(); + void updateRoleNames(); void updateFilterRole(); void updateSortRole(); void updateRoles();