From 692c0d3526b4bd5e5b17e17b4a6547046c2bfcbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Mon, 16 Jun 2014 14:10:09 +0200 Subject: Fix QQmlDelegateModel ignoring layoutChange in certain situations Fix a regression introduced by commit a0aefe1 which caused the model to ignore layout changes if d->m_adaptorModel.rootIndex was just a descendant of any of the parent indexes, or when no parent indexes at all were provided in the notification. Task-number: QTBUG-39492 Change-Id: I4c97929d25ef75947ccfcbbe5bc234096689c58d Reviewed-by: Alan Alpert --- .../auto/quick/qquicklistview/data/qtbug39492.qml | 40 ++++++++++ .../quick/qquicklistview/tst_qquicklistview.cpp | 88 +++++++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quick/qquicklistview/data/qtbug39492.qml (limited to 'tests') diff --git a/tests/auto/quick/qquicklistview/data/qtbug39492.qml b/tests/auto/quick/qquicklistview/data/qtbug39492.qml new file mode 100644 index 0000000000..4df3a080d7 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug39492.qml @@ -0,0 +1,40 @@ +import QtQuick 2.0 +import QtQml.Models 2.1 + +Rectangle { + id: root + width: 240 + height: 320 + color: "#ffffff" + + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + objectName: "delegateText" + text: display + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + DelegateModel { + id: delegateModel + objectName: "delegateModel" + model: testModel + delegate: myDelegate + } + + ListView { + id: list + objectName: "listView" + model: delegateModel; + focus: true + anchors.fill: parent + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 2093265163..f267b93b26 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -41,6 +41,8 @@ #include #include +#include +#include #include #include #include @@ -50,6 +52,7 @@ #include #include #include +#include #include "../../shared/util.h" #include "../shared/viewtestutil.h" #include "../shared/visualtestutil.h" @@ -62,6 +65,7 @@ Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection) Q_DECLARE_METATYPE(QQuickItemView::PositionMode) Q_DECLARE_METATYPE(QQuickListView::Orientation) Q_DECLARE_METATYPE(Qt::Key) +Q_DECLARE_METATYPE(QPersistentModelIndex) using namespace QQuickViewTestUtil; using namespace QQuickVisualTestUtil; @@ -228,6 +232,9 @@ private slots: void roundingErrors(); void roundingErrors_data(); + void QTBUG_39492_data(); + void QTBUG_39492(); + private: template void items(const QUrl &source); template void changed(const QUrl &source); @@ -7309,8 +7316,85 @@ void tst_QQuickListView::roundingErrors_data() QTest::newRow("pixelAligned=false") << false; } -QTEST_MAIN(tst_QQuickListView) +void tst_QQuickListView::QTBUG_39492_data() +{ + QStandardItemModel *sourceModel = new QStandardItemModel(this); + for (int i = 0; i < 5; ++i) { + QStandardItem *item = new QStandardItem(QString::number(i)); + for (int j = 0; j < 5; ++j) { + QStandardItem *subItem = new QStandardItem(QString("%1-%2").arg(i).arg(j)); + item->appendRow(subItem); + } + sourceModel->appendRow(item); + } -#include "tst_qquicklistview.moc" + QSortFilterProxyModel *sortModel = new QSortFilterProxyModel(this); + sortModel->setSourceModel(sourceModel); + + QTest::addColumn("model"); + QTest::addColumn("rootIndex"); + + QTest::newRow("invalid rootIndex") + << sortModel + << QPersistentModelIndex(); + + QTest::newRow("rootIndex 1") + << sortModel + << QPersistentModelIndex(sortModel->index(1, 0)); + + QTest::newRow("rootIndex 3") + << sortModel + << QPersistentModelIndex(sortModel->index(3, 0)); + + const QModelIndex rootIndex2 = sortModel->index(2, 0); + QTest::newRow("rootIndex 2-1") + << sortModel + << QPersistentModelIndex(sortModel->index(1, 0, rootIndex2)); +} + +void tst_QQuickListView::QTBUG_39492() +{ + QFETCH(QSortFilterProxyModel*, model); + QFETCH(QPersistentModelIndex, rootIndex); + + QQuickView *window = getView(); + window->rootContext()->setContextProperty("testModel", QVariant::fromValue(model)); + window->setSource(testFileUrl("qtbug39492.qml")); + QQuickListView *listview = window->rootObject()->findChild("listView"); + QVERIFY(listview); + + QQmlDelegateModel *delegateModel = window->rootObject()->findChild("delegateModel"); + QVERIFY(delegateModel); + + delegateModel->setRootIndex(QVariant::fromValue(QModelIndex(rootIndex))); + model->sort(0, Qt::AscendingOrder); + listview->forceLayout(); + + for (int i = 0; i < model->rowCount(rootIndex); ++i) { + QQuickItem *delegateItem = listview->itemAt(10, 10 + i * 20); + QVERIFY(delegateItem); + QQuickItem *delegateText = delegateItem->findChild("delegateText"); + QVERIFY(delegateText); + QCOMPARE(delegateText->property("text").toString(), + model->index(i, 0, rootIndex).data().toString()); + } + + model->sort(0, Qt::DescendingOrder); + listview->forceLayout(); + for (int i = 0; i < model->rowCount(rootIndex); ++i) { + QQuickItem *delegateItem = listview->itemAt(10, 10 + i * 20); + QVERIFY(delegateItem); + QQuickItem *delegateText = delegateItem->findChild("delegateText"); + QVERIFY(delegateText); + QCOMPARE(delegateText->property("text").toString(), + model->index(i, 0, rootIndex).data().toString()); + } + + releaseView(window); +} + +QTEST_MAIN(tst_QQuickListView) + +#include "tst_qquicklistview.moc" -- cgit v1.2.3 From 47ffb30a69285d6ced1287f14ff5842a298e60e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Tue, 29 Jul 2014 11:11:11 +0200 Subject: Fix QQmlDelegateModel getting out of sync Fixes a regression introduced by a0aefe1, which caused that the source data model and adaptorModel could sometimes get out of sync. Change-Id: Ia6b5fc380cc6cf6549ae857e6da54e088a5dadb5 Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com> --- .../quick/qquicklistview/data/layoutChangeSort.qml | 58 +++++++++++ tests/auto/quick/qquicklistview/qquicklistview.pro | 7 +- .../auto/quick/qquicklistview/randomsortmodel.cpp | 107 +++++++++++++++++++++ tests/auto/quick/qquicklistview/randomsortmodel.h | 64 ++++++++++++ .../quick/qquicklistview/tst_qquicklistview.cpp | 38 ++++++++ 5 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quick/qquicklistview/data/layoutChangeSort.qml create mode 100644 tests/auto/quick/qquicklistview/randomsortmodel.cpp create mode 100644 tests/auto/quick/qquicklistview/randomsortmodel.h (limited to 'tests') diff --git a/tests/auto/quick/qquicklistview/data/layoutChangeSort.qml b/tests/auto/quick/qquicklistview/data/layoutChangeSort.qml new file mode 100644 index 0000000000..e54f164e45 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/layoutChangeSort.qml @@ -0,0 +1,58 @@ +import QtQuick 2.0 +import QtQml.Models 2.1 + +Rectangle { + id: root + width: 240 + height: 320 + color: "#ffffff" + + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + objectName: "delegateText" + text: display + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + DelegateModel { + id: delegateModel + objectName: "delegateModel" + model: testModel + delegate: myDelegate + } + + ListView { + id: list + objectName: "listView" + model: delegateModel; + focus: true + anchors.fill: parent + + + section { + property: "SortRole"; + delegate: Rectangle { + width: parent.width; + height: 20; + color: "steelblue"; + + Text { + anchors { + fill: parent; + margins: 5; + } + text: section; + } + } + } + } +} diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro index 2ae04d32fe..c9b634b9e8 100644 --- a/tests/auto/quick/qquicklistview/qquicklistview.pro +++ b/tests/auto/quick/qquicklistview/qquicklistview.pro @@ -4,10 +4,13 @@ TARGET = tst_qquicklistview macx:CONFIG -= app_bundle HEADERS += incrementalmodel.h \ - proxytestinnermodel.h + proxytestinnermodel.h \ + randomsortmodel.h SOURCES += tst_qquicklistview.cpp \ incrementalmodel.cpp \ - proxytestinnermodel.cpp + proxytestinnermodel.cpp \ + randomsortmodel.cpp + include (../../shared/util.pri) include (../shared/util.pri) diff --git a/tests/auto/quick/qquicklistview/randomsortmodel.cpp b/tests/auto/quick/qquicklistview/randomsortmodel.cpp new file mode 100644 index 0000000000..e9082e39c9 --- /dev/null +++ b/tests/auto/quick/qquicklistview/randomsortmodel.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc 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 "randomsortmodel.h" + +RandomSortModel::RandomSortModel(QObject* parent): + QAbstractListModel(parent) +{ + for (int i = 0; i < 10; ++i) { + mData.append(qMakePair(QString::fromLatin1("Item %1").arg(i), i * 10)); + } +} + +QHash RandomSortModel::roleNames() const +{ + QHash roles = QAbstractItemModel::roleNames(); + roles[Qt::UserRole] = "SortRole"; + return roles; +} + + +int RandomSortModel::rowCount(const QModelIndex& parent) const +{ + if (!parent.isValid()) + return mData.count(); + + return 0; +} + +QVariant RandomSortModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() >= mData.count()) { + return QVariant(); + } + + if (role == Qt::DisplayRole) { + return QString::fromLatin1("%1 (weight %2)").arg(mData[index.row()].first).arg(mData[index.row()].second); + } else if (role == Qt::UserRole) { + return mData[index.row()].second; + } + + return QVariant(); +} + +void RandomSortModel::randomize() +{ + const int row = qrand() % mData.count(); + int random; + bool exists = false; + // Make sure we won't end up with two items with the same weight, as that + // would make unit-testing much harder + do { + exists = false; + random = qrand() % (mData.count() * 10); + QList >::ConstIterator iter, end; + for (iter = mData.constBegin(), end = mData.constEnd(); iter != end; ++iter) { + if ((*iter).second == random) { + exists = true; + break; + } + } + } while (exists); + mData[row].second = random; + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} diff --git a/tests/auto/quick/qquicklistview/randomsortmodel.h b/tests/auto/quick/qquicklistview/randomsortmodel.h new file mode 100644 index 0000000000..8d28698d9b --- /dev/null +++ b/tests/auto/quick/qquicklistview/randomsortmodel.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc 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 RANDOMSORTMODEL_H +#define RANDOMSORTMODEL_H + +#include + +class RandomSortModel : public QAbstractListModel +{ + Q_OBJECT + +public: + explicit RandomSortModel(QObject* parent = 0); + QHash roleNames() const; + + QVariant data(const QModelIndex& index, int role) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + + void randomize(); + + private: + QList > mData; +}; + +#endif // RANDOMSORTMODEL_H diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index b561258351..4fcf186690 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -55,6 +55,7 @@ #include "../shared/visualtestutil.h" #include "incrementalmodel.h" #include "proxytestinnermodel.h" +#include "randomsortmodel.h" #include Q_DECLARE_METATYPE(Qt::LayoutDirection) @@ -231,6 +232,8 @@ private slots: void QTBUG_38209(); void programmaticFlickAtBounds(); + void layoutChange(); + private: template void items(const QUrl &source); template void changed(const QUrl &source); @@ -7365,6 +7368,41 @@ void tst_QQuickListView::programmaticFlickAtBounds() QVERIFY(!spy.wait(100)); } +void tst_QQuickListView::layoutChange() +{ + RandomSortModel *model = new RandomSortModel; + QSortFilterProxyModel *sortModel = new QSortFilterProxyModel; + sortModel->setSourceModel(model); + sortModel->setSortRole(Qt::UserRole); + sortModel->setDynamicSortFilter(true); + sortModel->sort(0); + + QScopedPointer window(createView()); + window->rootContext()->setContextProperty("testModel", QVariant::fromValue(sortModel)); + window->setSource(testFileUrl("layoutChangeSort.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *listview = window->rootObject()->findChild("listView"); + QVERIFY(listview); + + for (int iter = 0; iter < 100; iter++) { + for (int i = 0; i < sortModel->rowCount(); ++i) { + QQuickItem *delegateItem = listview->itemAt(10, 10 + 2 * i * 20 + 20); // item + group + QVERIFY(delegateItem); + QQuickItem *delegateText = delegateItem->findChild("delegateText"); + QVERIFY(delegateText); + + QCOMPARE(delegateText->property("text").toString(), + sortModel->index(i, 0, QModelIndex()).data().toString()); + } + + model->randomize(); + listview->forceLayout(); + QTest::qWait(5); // give view a chance to update + } +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" -- cgit v1.2.3 From 3f5141e5b7227630ca89329a92b6ebddbcb1b7a5 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 1 Aug 2014 11:25:55 +0200 Subject: Run autotests for Canvas.renderTarget == FramebufferObject also. Change-Id: Id1729966b3b2b75a3bd4ad387b3d7914266fb3a5 Reviewed-by: Laszlo Agocs --- tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml index 70682bed0b..c8c2f4960f 100644 --- a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml +++ b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml @@ -19,8 +19,8 @@ TestCase { // { tag:"image cooperative", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Cooperative}}, { tag:"image immediate", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Immediate}}, // { tag:"fbo cooperative", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Cooperative}}, -// { tag:"fbo immediate", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Immediate}}, -// { tag:"fbo threaded", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Threaded}} + { tag:"fbo immediate", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Immediate}}, + { tag:"fbo threaded", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Threaded}} ]; return []; } -- cgit v1.2.3