From dee1fea683a887bd117d1532a9c6377ecdc01f30 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Mon, 25 Jan 2021 14:29:47 +0100 Subject: planner: implement move semantics in DivePlannerPointsModel When reordering the points, the DivePlannerPointsModel would not emit the appropriate move signals, but simply a data-changed signal over all elements. This obviously violates Qt's model/view API, though it is probably harmless. Let's do the right thing so that the frontend knows that the selected item changed place. Also, emit dataChanged only on the actually changed element, not all elements. Signed-off-by: Berthold Stoeger --- qt-models/diveplannermodel.cpp | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'qt-models') diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 2f9272415..f22dd931e 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -831,20 +831,49 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int cylinderid_ void DivePlannerPointsModel::editStop(int row, divedatapoint newData) { + if (row < 0 || row >= divepoints.count()) + return; + + // Refuse to move to 0, since that has special meaning. + if (newData.time <= 0) + return; + /* * When moving divepoints rigorously, we might end up with index * out of range, thus returning the last one instead. */ int old_first_cylid = divepoints[0].cylinderid; - if (row >= divepoints.count()) - return; + + // Is it ok to change data first and then move the rows? divepoints[row] = newData; - std::sort(divepoints.begin(), divepoints.end(), divePointsLessThan); + + // If the time changed, the item might have to be moved. Oh joy. + int newRow = row; + while (newRow + 1 < divepoints.count() && divepoints[newRow + 1].time < divepoints[row].time) + ++newRow; + if (newRow != row) { + ++newRow; // Move one past item with smaller time stamp + } else { + // If we didn't move forward, try moving backwards + while (newRow > 0 && divepoints[newRow - 1].time > divepoints[row].time) + --newRow; + } + + if (newRow != row && newRow != row + 1) { + beginMoveRows(QModelIndex(), row, row, QModelIndex(), newRow); + moveInVector(divepoints, row, row + 1, newRow); + endMoveRows(); + + // Account for moving the row backwards in the array. + row = newRow > row ? newRow - 1 : newRow; + } + if (updateMaxDepth()) cylinders.updateBestMixes(); if (divepoints[0].cylinderid != old_first_cylid) cylinders.moveAtFirst(divepoints[0].cylinderid); - emitDataChanged(); + + emit dataChanged(createIndex(row, 0), createIndex(row, COLUMNS - 1)); } int DivePlannerPointsModel::size() const -- cgit v1.2.3-70-g09d2