aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2018-08-01 22:53:17 +0200
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2018-08-02 15:53:58 +0000
commitfe1a259be66835bc937890f3ed62bb2e8496d0f1 (patch)
tree12453b09306764e679cb45af9de417c38101f572 /tests/auto/quick
parente997cd013a665505bd2d33a3e4b76e27752bcb39 (diff)
QQmlTableInstanceModel: handle model data changes more gracefully
Equal to QQmlDelegateModel, we need to listen for changes done to existing model items, and notify existing delegate items about it. Otherwise, they will not stay in sync with the model. By accident, this sort of worked in QQuickTableView already, since it would rebuild the whole table for every model update. This is really slow, and completely unnecessary. Change-Id: I10750ff387f8b455d0f27c50a17926d9beb6dd03 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qquicktableview/data/plaintableview.qml3
-rw-r--r--tests/auto/quick/qquicktableview/testmodel.h29
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp51
3 files changed, 73 insertions, 10 deletions
diff --git a/tests/auto/quick/qquicktableview/data/plaintableview.qml b/tests/auto/quick/qquicktableview/data/plaintableview.qml
index 36c28525d5..21373e6732 100644
--- a/tests/auto/quick/qquicktableview/data/plaintableview.qml
+++ b/tests/auto/quick/qquicktableview/data/plaintableview.qml
@@ -71,6 +71,9 @@ Item {
implicitHeight: delegateHeight
color: "lightgray"
border.width: 1
+
+ property string modelDataBinding: modelData
+
Text {
anchors.centerIn: parent
text: modelData
diff --git a/tests/auto/quick/qquicktableview/testmodel.h b/tests/auto/quick/qquicktableview/testmodel.h
index ab18af7871..56d5021cec 100644
--- a/tests/auto/quick/qquicktableview/testmodel.h
+++ b/tests/auto/quick/qquicktableview/testmodel.h
@@ -57,10 +57,10 @@ public:
if (!index.isValid() || role != Qt::DisplayRole)
return QVariant();
- int cell = index.row() + (index.column() * m_columns);
- if (selectedCells.contains(cell))
- return QStringLiteral("selected");
- return QString("%1").arg(index.row());
+ int serializedIndex = index.row() + (index.column() * m_columns);
+ if (modelData.contains(serializedIndex))
+ return modelData.value(serializedIndex);
+ return QStringLiteral("%1").arg(index.row());
}
QHash<int, QByteArray> roleNames() const override
@@ -68,12 +68,21 @@ public:
return { {Qt::DisplayRole, "display"} };
}
- Q_INVOKABLE void selectCell(int row, int column)
+ Q_INVOKABLE void setModelData(const QPoint &cell, const QSize &span, const QString &prefix)
{
- int cell = row + (column * m_columns);
- selectedCells.insert(cell);
- auto index = createIndex(row, column, nullptr);
- emit dataChanged(index, index);
+ for (int c = 0; c < span.width(); ++c) {
+ for (int r = 0; r < span.height(); ++r) {
+ const int changedRow = cell.y() + r;
+ const int changedColumn = cell.x() + c;
+ const int serializedIndex = changedRow + (changedColumn * m_rows);
+ const QString string = prefix + QStringLiteral("%1,%2").arg(changedColumn).arg(changedRow);
+ modelData.insert(serializedIndex, string);
+ }
+ }
+
+ const auto topLeftIndex = createIndex(cell.y(), cell.x(), nullptr);
+ const auto bottomRightIndex = createIndex(cell.y() + span.height() - 1, cell.x() + span.width() - 1, nullptr);
+ emit dataChanged(topLeftIndex, bottomRightIndex);
}
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override
@@ -134,7 +143,7 @@ signals:
private:
int m_rows = 0;
int m_columns = 0;
- QSet<int> selectedCells;
+ QHash<int, QString> modelData;
};
#define TestModelAsVariant(...) QVariant::fromValue(QSharedPointer<TestModel>(new TestModel(__VA_ARGS__)))
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 86839b61dc..bc0990862f 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -51,6 +51,7 @@ using namespace QQuickVisualTestUtil;
static const char* kTableViewPropName = "tableView";
static const char* kDelegateObjectName = "tableViewDelegate";
static const char *kDelegatesCreatedCountProp = "delegatesCreatedCount";
+static const char *kModelDataBindingProp = "modelDataBinding";
Q_DECLARE_METATYPE(QMarginsF);
@@ -113,6 +114,7 @@ private slots:
void flickOvershoot();
void checkRowColumnCount();
void modelSignals();
+ void dataChangedSignal();
void checkIfDelegatesAreReused_data();
void checkIfDelegatesAreReused();
void checkContextProperties_data();
@@ -1113,6 +1115,55 @@ void tst_QQuickTableView::modelSignals()
QCOMPARE(tableView->columns(), 1);
}
+void tst_QQuickTableView::dataChangedSignal()
+{
+ // Check that bindings to the model inside a delegate gets updated
+ // when the model item they bind to changes.
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ const QString prefix(QStringLiteral("changed"));
+
+ TestModel model(10, 10);
+ tableView->setModel(QVariant::fromValue(&model));
+
+ WAIT_UNTIL_POLISHED;
+
+ for (auto fxItem : tableViewPrivate->loadedItems) {
+ const auto item = tableViewPrivate->loadedTableItem(fxItem->cell)->item;
+ const QString modelDataBindingProperty = item->property(kModelDataBindingProp).toString();
+ QString expectedModelData = QString::number(fxItem->cell.y());
+ QCOMPARE(modelDataBindingProperty, expectedModelData);
+ }
+
+ // Change one cell in the model
+ model.setModelData(QPoint(0, 0), QSize(1, 1), prefix);
+
+ for (auto fxItem : tableViewPrivate->loadedItems) {
+ const QPoint cell = fxItem->cell;
+ const auto modelIndex = model.index(cell.y(), cell.x());
+ QString expectedModelData = model.data(modelIndex, Qt::DisplayRole).toString();
+
+ const auto item = tableViewPrivate->loadedTableItem(fxItem->cell)->item;
+ const QString modelDataBindingProperty = item->property(kModelDataBindingProp).toString();
+
+ QCOMPARE(modelDataBindingProperty, expectedModelData);
+ }
+
+ // Change four cells in one go
+ model.setModelData(QPoint(1, 0), QSize(2, 2), prefix);
+
+ for (auto fxItem : tableViewPrivate->loadedItems) {
+ const QPoint cell = fxItem->cell;
+ const auto modelIndex = model.index(cell.y(), cell.x());
+ QString expectedModelData = model.data(modelIndex, Qt::DisplayRole).toString();
+
+ const auto item = tableViewPrivate->loadedTableItem(fxItem->cell)->item;
+ const QString modelDataBindingProperty = item->property(kModelDataBindingProp).toString();
+
+ QCOMPARE(modelDataBindingProperty, expectedModelData);
+ }
+}
+
void tst_QQuickTableView::checkIfDelegatesAreReused_data()
{
QTest::addColumn<bool>("reuseItems");