From eecca6aab0a1970c7474df7ac8408d810a5d0bbd Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Thu, 26 Sep 2019 13:47:49 +0200 Subject: [PATCH] Mobile: replace model-reset by row-addition in DiveListModel::reload() Owing to apparent QML breakage, a model-reset leads to the DiveDetail page being reloaded for every dive in the list(!). Therefore, add rows instead. This leads to extremely subtle code, as it is now imperative that the model has been properly cleared beforehand. Nevertheless, for now we have to do this to fix a severe performance regression. Fixes #2295 Signed-off-by: Berthold Stoeger --- mobile-widgets/qml/DownloadFromDiveComputer.qml | 2 +- qt-models/divelistmodel.cpp | 14 +++++++++++--- qt-models/divelistmodel.h | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/mobile-widgets/qml/DownloadFromDiveComputer.qml b/mobile-widgets/qml/DownloadFromDiveComputer.qml index 48fd816d8..51c96c044 100644 --- a/mobile-widgets/qml/DownloadFromDiveComputer.qml +++ b/mobile-widgets/qml/DownloadFromDiveComputer.qml @@ -391,7 +391,7 @@ Kirigami.Page { manager.appendTextToLog("Save downloaded dives that were selected") importModel.recordDives() manager.saveChangesLocal() - diveModel.reload() + diveModel.resetInternaData() pageStack.pop(); download.text = qsTr("Download") divesDownloaded = false diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp index 6f7d69412..9aa78f344 100644 --- a/qt-models/divelistmodel.cpp +++ b/qt-models/divelistmodel.cpp @@ -73,7 +73,7 @@ int DiveListSortModel::getIdxForId(int id) void DiveListSortModel::reload() { DiveListModel *mySourceModel = qobject_cast(sourceModel()); - mySourceModel->reload(); + mySourceModel->resetInternalData(); } // In QtQuick ListView, section headings can only be strings. To identify dives @@ -180,8 +180,16 @@ void DiveListModel::clear() void DiveListModel::reload() { - beginResetModel(); - endResetModel(); + // Note: instead of doing a (logical) beginResetModel()/endResetModel(), + // we add the rows (if any). The reason is that a beginResetModel()/endResetModel() + // pair resulted in the DiveDetailsPage being renedered for *every* dive in + // the list. It is unclear whether this is a Qt-bug or intended insanity. + // Therefore, this function must only be called after having called clear(). + // Otherwise the model will become inconsistent! + if (dive_table.nr > 0) { + beginInsertRows(QModelIndex(), 0, dive_table.nr - 1); + endInsertRows(); + } } void DiveListModel::resetInternalData() diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h index 686dcd1c3..19838f468 100644 --- a/qt-models/divelistmodel.h +++ b/qt-models/divelistmodel.h @@ -53,7 +53,7 @@ public: void removeDive(int i); void removeDiveById(int id); void updateDive(int i, dive *d); - void reload(); + void reload(); // Only call after clearing the model! struct dive *getDive(int i); int rowCount(const QModelIndex &parent = QModelIndex()) const; int getDiveIdx(int id) const;