aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/types
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 /src/qml/types
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 'src/qml/types')
-rw-r--r--src/qml/types/qqmltableinstancemodel.cpp19
-rw-r--r--src/qml/types/qqmltableinstancemodel_p.h2
2 files changed, 21 insertions, 0 deletions
diff --git a/src/qml/types/qqmltableinstancemodel.cpp b/src/qml/types/qqmltableinstancemodel.cpp
index 6604e009c1..536dd46182 100644
--- a/src/qml/types/qqmltableinstancemodel.cpp
+++ b/src/qml/types/qqmltableinstancemodel.cpp
@@ -437,7 +437,26 @@ void QQmlTableInstanceModel::setModel(const QVariant &model)
// needs to stay in sync with the model. So we need to drain the pool
// completely when the model changes.
drainReusableItemsPool(0);
+ if (auto const aim = abstractItemModel())
+ disconnect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback);
m_adaptorModel.setModel(model, this, m_qmlContext->engine());
+ if (auto const aim = abstractItemModel())
+ connect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback);
+}
+
+void QQmlTableInstanceModel::dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+{
+ // This function is called when model data has changed. In that case, we tell the adaptor model
+ // to go through all the items we have created, find the ones that are affected, and notify that
+ // their model data has changed. This will in turn update QML bindings inside the delegate items.
+ int numberOfRowsChanged = end.row() - begin.row() + 1;
+ int numberOfColumnsChanged = end.column() - begin.column() + 1;
+
+ for (int column = 0; column < numberOfColumnsChanged; ++column) {
+ const int columnIndex = begin.column() + column;
+ const int rowIndex = begin.row() + (columnIndex * rows());
+ m_adaptorModel.notify(m_modelItems.values(), rowIndex, numberOfRowsChanged, roles);
+ }
}
QQmlComponent *QQmlTableInstanceModel::delegate() const
diff --git a/src/qml/types/qqmltableinstancemodel_p.h b/src/qml/types/qqmltableinstancemodel_p.h
index 23243e7f0e..71689ce6da 100644
--- a/src/qml/types/qqmltableinstancemodel_p.h
+++ b/src/qml/types/qqmltableinstancemodel_p.h
@@ -142,6 +142,8 @@ private:
void deleteAllFinishedIncubationTasks();
QQmlDelegateModelItem *resolveModelItem(int index);
+ void dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles);
+
static bool isDoneIncubating(QQmlDelegateModelItem *modelItem);
static void deleteModelItemLater(QQmlDelegateModelItem *modelItem);