diff options
3 files changed, 75 insertions, 7 deletions
diff --git a/src/qmlmodels/sfpm/qqmlsortfilterproxymodel.cpp b/src/qmlmodels/sfpm/qqmlsortfilterproxymodel.cpp index 9988766aef..aa7e662192 100644 --- a/src/qmlmodels/sfpm/qqmlsortfilterproxymodel.cpp +++ b/src/qmlmodels/sfpm/qqmlsortfilterproxymodel.cpp @@ -446,7 +446,7 @@ QItemSelection QQmlSortFilterProxyModel::mapSelectionFromSource(const QItemSelec QModelIndex QQmlSortFilterProxyModel::index(int row, int column, const QModelIndex &parent) const { Q_D(const QQmlSortFilterProxyModel); - if (row < 0 || column < 0) + if (row < 0 || column < 0 || !sourceModel()) return QModelIndex(); QModelIndex source_parent = mapToSource(parent); // parent is already mapped at this point @@ -510,7 +510,7 @@ bool QQmlSortFilterProxyModel::hasChildren(const QModelIndex &parent) const int QQmlSortFilterProxyModel::columnCount(const QModelIndex &parent) const { Q_D(const QQmlSortFilterProxyModel); - if (!d->model) + if (!sourceModel()) return 0; QModelIndex source_parent = mapToSource(parent); if (parent.isValid() && !source_parent.isValid()) @@ -522,7 +522,7 @@ int QQmlSortFilterProxyModel::columnCount(const QModelIndex &parent) const int QQmlSortFilterProxyModel::rowCount(const QModelIndex &parent) const { Q_D(const QQmlSortFilterProxyModel); - if (!d->model) + if (!sourceModel()) return 0; QModelIndex source_parent = mapToSource(parent); if (parent.isValid() && !source_parent.isValid()) @@ -555,6 +555,8 @@ bool QQmlSortFilterProxyModel::setData(const QModelIndex &index, const QVariant QVariant QQmlSortFilterProxyModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_D(const QQmlSortFilterProxyModel); + if (!sourceModel()) + return QVariant(); QSortFilterProxyModelHelper::IndexMap::const_iterator it = d->create_mapping(QModelIndex()); if (it.value()->source_rows.size() * it.value()->source_columns.size() > 0) return QAbstractProxyModel::headerData(section, orientation, role); @@ -578,6 +580,8 @@ bool QQmlSortFilterProxyModel::setHeaderData(int section, Qt::Orientation orient const QVariant &value, int role) { Q_D(QQmlSortFilterProxyModel); + if (!sourceModel()) + return false; QSortFilterProxyModelHelper::IndexMap::const_iterator it = d->create_mapping(QModelIndex()); if (it.value()->source_rows.size() * it.value()->source_columns.size() > 0) return QAbstractProxyModel::setHeaderData(section, orientation, value, role); @@ -600,7 +604,7 @@ bool QQmlSortFilterProxyModel::setHeaderData(int section, Qt::Orientation orient bool QQmlSortFilterProxyModel::insertRows(int row, int count, const QModelIndex &parent) { Q_D(QQmlSortFilterProxyModel); - if (row < 0 || count <= 0) + if (row < 0 || count <= 0 || !sourceModel()) return false; QModelIndex source_parent = mapToSource(parent); if (parent.isValid() && !source_parent.isValid()) @@ -620,7 +624,7 @@ bool QQmlSortFilterProxyModel::insertRows(int row, int count, const QModelIndex bool QQmlSortFilterProxyModel::insertColumns(int column, int count, const QModelIndex &parent) { Q_D(QQmlSortFilterProxyModel); - if (column < 0|| count <= 0) + if (column < 0 || count <= 0 || !sourceModel()) return false; QModelIndex source_parent = mapToSource(parent); if (parent.isValid() && !source_parent.isValid()) @@ -640,7 +644,7 @@ bool QQmlSortFilterProxyModel::insertColumns(int column, int count, const QModel bool QQmlSortFilterProxyModel::removeRows(int row, int count, const QModelIndex &parent) { Q_D(QQmlSortFilterProxyModel); - if (row < 0 || count <= 0) + if (row < 0 || count <= 0 || !sourceModel()) return false; QModelIndex source_parent = mapToSource(parent); if (parent.isValid() && !source_parent.isValid()) @@ -682,7 +686,7 @@ bool QQmlSortFilterProxyModel::removeRows(int row, int count, const QModelIndex bool QQmlSortFilterProxyModel::removeColumns(int column, int count, const QModelIndex &parent) { Q_D(QQmlSortFilterProxyModel); - if (column < 0 || count <= 0) + if (column < 0 || count <= 0 || !sourceModel()) return false; QModelIndex source_parent = mapToSource(parent); if (parent.isValid() && !source_parent.isValid()) diff --git a/tests/auto/qml/qqmlsortfilterproxymodel/data/sfpmProxyChain.qml b/tests/auto/qml/qqmlsortfilterproxymodel/data/sfpmProxyChain.qml new file mode 100644 index 0000000000..445aef2e60 --- /dev/null +++ b/tests/auto/qml/qqmlsortfilterproxymodel/data/sfpmProxyChain.qml @@ -0,0 +1,11 @@ +import QtQml + +QtObject { + // The inner proxy deliberately has no source model. + property SortFilterProxyModel innerProxyModel: SortFilterProxyModel {} + + property SortFilterProxyModel outerProxyModel: SortFilterProxyModel { + sourceModel: innerProxyModel + sorters: RoleSorter { roleName: "display" } + } +} diff --git a/tests/auto/qml/qqmlsortfilterproxymodel/tst_qqmlsortfilterproxymodel.cpp b/tests/auto/qml/qqmlsortfilterproxymodel/tst_qqmlsortfilterproxymodel.cpp index 9f73c0881e..b22996d5b9 100644 --- a/tests/auto/qml/qqmlsortfilterproxymodel/tst_qqmlsortfilterproxymodel.cpp +++ b/tests/auto/qml/qqmlsortfilterproxymodel/tst_qqmlsortfilterproxymodel.cpp @@ -58,6 +58,8 @@ private slots: void primarySorter(); void primaryColumnWithoutSourceModel(); + void queriesWithoutSourceModel(); + void proxyOfProxyWithoutSourceModel(); void anyOfFilter(); void allOfFilter(); @@ -1175,6 +1177,57 @@ void tst_QQmlSortFilterProxyModel::primaryColumnWithoutSourceModel() sfpmModel->setPrimarySortColumn(1); } +void tst_QQmlSortFilterProxyModel::queriesWithoutSourceModel() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("sfpmCommon.qml")); + QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8()); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + auto *sfpmModel = object->property("sfpmProxyModel").value<QQmlSortFilterProxyModel *>(); + QVERIFY(sfpmModel); + QVERIFY(!sfpmModel->sourceModel()); + + // These used to assert in create_mapping() because no source model was set. + QCOMPARE(sfpmModel->rowCount(), 0); + QCOMPARE(sfpmModel->columnCount(), 0); + QVERIFY(!sfpmModel->index(0, 0).isValid()); + QVERIFY(!sfpmModel->headerData(0, Qt::Horizontal).isValid()); + QVERIFY(!sfpmModel->setHeaderData(0, Qt::Horizontal, QStringLiteral("header"))); + QVERIFY(!sfpmModel->insertRows(0, 1)); + QVERIFY(!sfpmModel->insertColumns(0, 1)); + QVERIFY(!sfpmModel->removeRows(0, 1)); + QVERIFY(!sfpmModel->removeColumns(0, 1)); +} + +void tst_QQmlSortFilterProxyModel::proxyOfProxyWithoutSourceModel() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("sfpmProxyChain.qml")); + QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8()); + // Setting the outer proxy's source used to assert in create_mapping(), + // because the inner proxy has no source model of its own. + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + auto *innerProxyModel = object->property("innerProxyModel").value<QQmlSortFilterProxyModel *>(); + QVERIFY(innerProxyModel); + QVERIFY(!innerProxyModel->sourceModel()); + auto *outerProxyModel = object->property("outerProxyModel").value<QQmlSortFilterProxyModel *>(); + QVERIFY(outerProxyModel); + QCOMPARE(outerProxyModel->sourceModel(), innerProxyModel); + QCOMPARE(outerProxyModel->rowCount(), 0); + + // Once the inner proxy gets a source, its rows should show up in the outer one. + QStandardItemModel sourceModel; + for (int rowIndex = 0; rowIndex < 3; ++rowIndex) + sourceModel.appendRow(new QStandardItem(QStringLiteral("item"))); + innerProxyModel->setSourceModel(&sourceModel); + QCOMPARE(innerProxyModel->rowCount(), 3); + QCOMPARE(outerProxyModel->rowCount(), 3); +} + void tst_QQmlSortFilterProxyModel::anyOfFilter() { QQmlEngine engine; |
