aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlmodels/sfpm/qqmlsortfilterproxymodel.cpp18
-rw-r--r--tests/auto/qml/qqmlsortfilterproxymodel/data/sfpmProxyChain.qml11
-rw-r--r--tests/auto/qml/qqmlsortfilterproxymodel/tst_qqmlsortfilterproxymodel.cpp53
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;