Reset on model layout changed
authorAlbert Astals Cid <albert.astals@canonical.com>
Wed, 16 Oct 2013 15:20:59 +0000 (17:20 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 21 Oct 2013 07:09:15 +0000 (09:09 +0200)
Otherwise the next dataChanged from the model may not be received

Change-Id: I16b859d92fdb1823c4a56c297d4451abe438fbb1
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
src/qml/types/qqmldelegatemodel.cpp
tests/auto/quick/qquicklistview/data/proxytest.qml [new file with mode: 0644]
tests/auto/quick/qquicklistview/proxytestinnermodel.cpp [new file with mode: 0644]
tests/auto/quick/qquicklistview/proxytestinnermodel.h [new file with mode: 0644]
tests/auto/quick/qquicklistview/qquicklistview.pro
tests/auto/quick/qquicklistview/tst_qquicklistview.cpp

index 179dcfe..10f957a 100644 (file)
@@ -1524,8 +1524,7 @@ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelInd
 
 void QQmlDelegateModel::_q_layoutChanged()
 {
-    Q_D(QQmlDelegateModel);
-    _q_itemsChanged(0, d->m_count, QVector<int>());
+    _q_modelReset();
 }
 
 QQmlDelegateModelAttached *QQmlDelegateModel::qmlAttachedProperties(QObject *obj)
diff --git a/tests/auto/quick/qquicklistview/data/proxytest.qml b/tests/auto/quick/qquicklistview/data/proxytest.qml
new file mode 100644 (file)
index 0000000..ce713d3
--- /dev/null
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Canonical Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import Proxy 1.0
+
+Item {
+
+    ProxyTestInnerModel {
+        id: innerModel
+    }
+
+    QSortFilterProxyModel {
+        id: outerModel
+        sourceModel: innerModel
+        filterRegExp: RegExp("^H.*$")
+    }
+
+    width: 400
+    height: 400
+    ListView {
+        anchors.fill: parent
+        orientation: Qt.Vertical
+        model: outerModel
+        delegate: Rectangle {
+            width: 400
+            height: 50
+            color: index % 2 ? "red" : "yellow"
+        }
+    }
+
+    Timer {
+        running: true
+        interval: 500
+        onTriggered: {
+            innerModel.doStuff();
+        }
+    }
+}
diff --git a/tests/auto/quick/qquicklistview/proxytestinnermodel.cpp b/tests/auto/quick/qquicklistview/proxytestinnermodel.cpp
new file mode 100644 (file)
index 0000000..80b59f2
--- /dev/null
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Canonical Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "proxytestinnermodel.h"
+
+ProxyTestInnerModel::ProxyTestInnerModel()
+{
+    append("Adios");
+    append("Hola");
+    append("Halo");
+}
+
+QModelIndex ProxyTestInnerModel::index(int row, int column, const QModelIndex &parent) const
+{
+    if (parent.isValid())
+        return QModelIndex();
+
+    return createIndex(row, column);
+}
+
+QModelIndex ProxyTestInnerModel::parent(const QModelIndex & /*parent*/) const
+{
+    return QModelIndex();
+}
+
+int ProxyTestInnerModel::rowCount(const QModelIndex &parent) const
+{
+    if (parent.isValid())
+        return 0;
+
+    return m_values.count();
+}
+
+int ProxyTestInnerModel::columnCount(const QModelIndex &parent) const
+{
+    if (parent.isValid())
+        return 0;
+
+    return 1;
+}
+
+QVariant ProxyTestInnerModel::data(const QModelIndex &index, int role) const
+{
+    if (role != Qt::DisplayRole)
+        return QVariant();
+
+    return m_values[index.row()];
+}
+
+void ProxyTestInnerModel::append(const QString &s)
+{
+    beginInsertRows(QModelIndex(), m_values.count(), m_values.count());
+    m_values << s;
+    endInsertRows();
+}
+
+void ProxyTestInnerModel::setValue(int i, const QString &s)
+{
+    m_values[i] = s;
+    Q_EMIT dataChanged(index(i, 0), index(i, 0));
+}
+
+void ProxyTestInnerModel::moveTwoToZero()
+{
+    beginMoveRows(QModelIndex(), 2, 2, QModelIndex(), 0);
+    m_values.move(2, 0);
+    endMoveRows();
+}
+
+void ProxyTestInnerModel::doStuff()
+{
+    moveTwoToZero();
+    setValue(1, "Hilo");
+}
diff --git a/tests/auto/quick/qquicklistview/proxytestinnermodel.h b/tests/auto/quick/qquicklistview/proxytestinnermodel.h
new file mode 100644 (file)
index 0000000..1983e69
--- /dev/null
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Canonical Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INNERMODEL_H
+#define INNERMODEL_H
+
+#include <QAbstractItemModel>
+
+class ProxyTestInnerModel : public QAbstractItemModel
+{
+    Q_OBJECT
+public:
+    ProxyTestInnerModel();
+    virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+    virtual QModelIndex parent(const QModelIndex & /*parent*/) const;
+    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual int columnCount(const QModelIndex &parent) const;
+    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+    Q_INVOKABLE void doStuff();
+
+private:
+    void append(const QString &s);
+    void setValue(int i, const QString &s);
+    void moveTwoToZero();
+
+private:
+    QList<QString> m_values;
+};
+
+#endif
index a745c1a..4ac4767 100644 (file)
@@ -3,9 +3,11 @@ testcase.timeout = 900 # this test is slow
 TARGET = tst_qquicklistview
 macx:CONFIG -= app_bundle
 
-HEADERS += incrementalmodel.h
+HEADERS += incrementalmodel.h \
+           proxytestinnermodel.h
 SOURCES += tst_qquicklistview.cpp \
-           incrementalmodel.cpp
+           incrementalmodel.cpp \
+           proxytestinnermodel.cpp
 
 include (../../shared/util.pri)
 include (../shared/util.pri)
index 5b1dfc7..f62151c 100644 (file)
@@ -54,6 +54,7 @@
 #include "../shared/viewtestutil.h"
 #include "../shared/visualtestutil.h"
 #include "incrementalmodel.h"
+#include "proxytestinnermodel.h"
 #include <math.h>
 
 Q_DECLARE_METATYPE(Qt::LayoutDirection)
@@ -210,6 +211,7 @@ private slots:
     void accessEmptyCurrentItem_QTBUG_30227();
     void delayedChanges_QTBUG_30555();
     void outsideViewportChangeNotAffectingView();
+    void testProxyModelChangedAfterMove();
 
 private:
     template <class T> void items(const QUrl &source);
@@ -319,6 +321,9 @@ void tst_QQuickListView::init()
         m_view = 0;
     }
 #endif
+    qmlRegisterType<QAbstractItemModel>();
+    qmlRegisterType<ProxyTestInnerModel>("Proxy", 1, 0, "ProxyTestInnerModel");
+    qmlRegisterType<QSortFilterProxyModel>("Proxy", 1, 0, "QSortFilterProxyModel");
 }
 
 void tst_QQuickListView::cleanupTestCase()
@@ -6938,6 +6943,23 @@ void tst_QQuickListView::outsideViewportChangeNotAffectingView()
     delete window;
 }
 
+void tst_QQuickListView::testProxyModelChangedAfterMove()
+{
+    QQuickView *window = createView();
+    QQuickViewTestUtil::moveMouseAway(window);
+    window->setSource(testFileUrl("proxytest.qml"));
+
+    QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>();
+    QTRY_VERIFY(listview != 0);
+
+    window->show();
+    QVERIFY(QTest::qWaitForWindowExposed(window));
+
+    QTRY_COMPARE(listview->count(), 3);
+
+    delete window;
+}
+
 QTEST_MAIN(tst_QQuickListView)
 
 #include "tst_qquicklistview.moc"