Be specific about what part of the model is being re-layouted.
authorStephen Kelly <stephen.kelly@kdab.com>
Thu, 24 Nov 2011 20:21:28 +0000 (21:21 +0100)
committerQt by Nokia <qt-info@nokia.com>
Fri, 25 Nov 2011 13:37:02 +0000 (14:37 +0100)
Change-Id: I6b6fe98929543447f945a335c33960823c0d1a4a
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
src/widgets/itemviews/qsortfilterproxymodel.cpp
tests/auto/widgets/itemviews/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp

index 4810d6e..f8d5dcb 100644 (file)
@@ -1155,8 +1155,10 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
     }
 
     if (!source_rows_resort.isEmpty()) {
-        // Re-sort the rows
-        emit q->layoutAboutToBeChanged();
+        // Re-sort the rows of this level
+        QList<QPersistentModelIndex> parents;
+        parents << q->mapFromSource(source_parent);
+        emit q->layoutAboutToBeChanged(parents);
         QModelIndexPairList source_indexes = store_persistent_indexes();
         remove_source_items(m->proxy_rows, m->source_rows, source_rows_resort,
                             source_parent, Qt::Vertical, false);
@@ -1164,7 +1166,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
         insert_source_items(m->proxy_rows, m->source_rows, source_rows_resort,
                             source_parent, Qt::Vertical, false);
         update_persistent_indexes(source_indexes);
-        emit q->layoutChanged();
+        emit q->layoutChanged(parents);
        // Make sure we also emit dataChanged for the rows
        source_rows_change += source_rows_resort;
     }
index 8e62841..46194ce 100644 (file)
@@ -150,6 +150,8 @@ private slots:
     void mapSelectionFromSource();
     void filteredColumns();
 
+    void testParentLayoutChanged();
+
 protected:
     void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
     void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
@@ -3210,5 +3212,72 @@ void tst_QSortFilterProxyModel::taskQTBUG_17812_resetInvalidate()
     QCOMPARE(ok, works);
 }
 
+Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
+
+void tst_QSortFilterProxyModel::testParentLayoutChanged()
+{
+    QStandardItemModel model;
+    QStandardItem *parentItem = model.invisibleRootItem();
+    for (int i = 0; i < 4; ++i) {
+        {
+            QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
+            parentItem->appendRow(item);
+        }
+        {
+            QStandardItem *item = new QStandardItem(QString("item 1%0").arg(i));
+            parentItem->appendRow(item);
+            parentItem = item;
+        }
+    }
+
+    QSortFilterProxyModel proxy;
+    proxy.sort(0, Qt::AscendingOrder);
+    proxy.setDynamicSortFilter(true);
+
+    proxy.setSourceModel(&model);
+
+    qRegisterMetaType<QList<QPersistentModelIndex> >();
+
+    QSignalSpy dataChangedSpy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+    // Verify that the no-arg signal is still emitted.
+    QSignalSpy layoutAboutToBeChangedSpy(&proxy, SIGNAL(layoutAboutToBeChanged()));
+    QSignalSpy layoutChangedSpy(&proxy, SIGNAL(layoutChanged()));
+
+    QSignalSpy parentsAboutToBeChangedSpy(&proxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>)));
+    QSignalSpy parentsChangedSpy(&proxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>)));
+
+    QStandardItem *item = model.invisibleRootItem()->child(1)->child(1);
+
+    // Ensure mapped:
+    proxy.mapFromSource(model.indexFromItem(item));
+
+    item->setData("Changed");
+
+    QCOMPARE(dataChangedSpy.size(), 1);
+    QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+    QCOMPARE(layoutChangedSpy.size(), 1);
+    QCOMPARE(parentsAboutToBeChangedSpy.size(), 1);
+    QCOMPARE(parentsChangedSpy.size(), 1);
+
+    QVariantList beforeSignal = parentsAboutToBeChangedSpy.first();
+    QVariantList afterSignal = parentsChangedSpy.first();
+
+    QCOMPARE(beforeSignal.size(), 1);
+    QCOMPARE(afterSignal.size(), 1);
+
+    QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >();
+    QList<QPersistentModelIndex> afterParents = afterSignal.first().value<QList<QPersistentModelIndex> >();
+
+    QCOMPARE(beforeParents.size(), 1);
+    QCOMPARE(afterParents.size(), 1);
+
+    QVERIFY(beforeParents.first().isValid());
+    QVERIFY(beforeParents.first() == afterParents.first());
+
+    QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1))));
+
+}
+
 QTEST_MAIN(tst_QSortFilterProxyModel)
 #include "tst_qsortfilterproxymodel.moc"