diff options
Diffstat (limited to 'qt-models')
-rw-r--r-- | qt-models/divetripmodel.cpp | 160 | ||||
-rw-r--r-- | qt-models/divetripmodel.h | 10 |
2 files changed, 114 insertions, 56 deletions
diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 63c111981..a2a72ded3 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -377,6 +377,7 @@ void DiveTripModelBase::clear() beginResetModel(); clear_dive_file_data(); clearData(); + oldCurrent = nullptr; emit diveListNotifier.divesSelected({}, nullptr); // Inform profile, etc of changed selection endResetModel(); } @@ -459,6 +460,34 @@ static ShownChange updateShownAll() return res; } +void DiveTripModelBase::currentChanged() +{ + if (oldCurrent == current_dive) + return; + + // On Desktop we use a signal to forward current-dive changed, on mobile we use ROLE_CURRENT. + // TODO: Unify - use the role for both. +#if defined(SUBSURFACE_MOBILE) + static QVector<int> roles = { CURRENT_ROLE }; + if (oldCurrent) { + QModelIndex oldIdx = diveToIdx(oldCurrent); + dataChanged(oldIdx, oldIdx, roles); + } + if (current_dive) { + QModelIndex newIdx = diveToIdx(current_dive); + dataChanged(newIdx, newIdx, roles); + } +#else + if (current_dive) { + QModelIndex newIdx = diveToIdx(current_dive); + emit currentDiveChanged(newIdx); + } else { + emit currentDiveChanged(QModelIndex()); + } +#endif + oldCurrent = current_dive; +} + // Find a range of matching elements in a vector. // Input parameters: // v: vector to be searched @@ -627,6 +656,9 @@ void DiveTripModelTree::populate() it->dives.push_back(d); } } + + // Remember the index of the current dive + oldCurrent = current_dive; } int DiveTripModelTree::rowCount(const QModelIndex &parent) const @@ -1036,6 +1068,13 @@ void DiveTripModelTree::divesDeleted(dive_trip *trip, bool deleteTrip, const QVe if (dives.empty()) return; + if (oldCurrent && std::find(dives.begin(), dives.end(), oldCurrent) != dives.end()) + oldCurrent = nullptr; + divesDeletedInternal(trip, deleteTrip, dives); // Tail call +} + +void DiveTripModelTree::divesDeletedInternal(dive_trip *trip, bool deleteTrip, const QVector<dive *> &dives) +{ if (!trip) { // This is outside of a trip. Delete top-level dives in batches. removeDivesTopLevel(dives); @@ -1173,7 +1212,7 @@ void DiveTripModelTree::divesMovedBetweenTrips(dive_trip *from, dive_trip *to, b // Unfortunately, removing the dives means that their selection is lost. // Thus, remember the selection and re-add it later. divesAdded(to, createTo, dives); - divesDeleted(from, deleteFrom, dives); + divesDeletedInternal(from, deleteFrom, dives); // Use internal version to keep current dive } void DiveTripModelTree::divesTimeChanged(timestamp_t delta, const QVector<dive *> &dives) @@ -1198,10 +1237,41 @@ void DiveTripModelTree::divesTimeChangedTrip(dive_trip *trip, timestamp_t delta, // Cheating! // Unfortunately, removing the dives means that their selection is lost. // Thus, remember the selection and re-add it later. - divesDeleted(trip, false, dives); + divesDeletedInternal(trip, false, dives); // Use internal version to keep current dive divesAdded(trip, false, dives); } +QModelIndex DiveTripModelTree::diveToIdx(const dive *d) const +{ + if (!d) + return QModelIndex(); + dive_trip *trip = d->divetrip; + if (!trip) { + // Outside of a trip - search top-level. + int idx = findDiveIdx(d); + if (idx < 0) { + // We don't know this dive. Something is wrong. Warn and bail. + qWarning() << "DiveTripModelTree::diveToIdx(): unknown top-level dive"; + return QModelIndex(); + } + return createIndex(idx, 0, noParent); + } else { + int idx = findTripIdx(trip); + if (idx < 0) { + // We don't know the trip - this shouldn't happen. Warn and bail. + qWarning() << "DiveTripModelTree::diveToIdx(): unknown trip"; + return QModelIndex(); + } + int diveIdx = findDiveInTrip(idx, d); + if (diveIdx < 0) { + // We don't know this dive. Something is wrong. Warn and bail. + qWarning() << "DiveTripModelTree::diveToIdx(): unknown dive"; + return QModelIndex(); + } + return createIndex(diveIdx, 0, idx); + } +} + void DiveTripModelTree::divesSelected(const QVector<dive *> &divesIn, dive *current) { QVector <dive *> dives = visibleDives(divesIn); @@ -1219,39 +1289,7 @@ void DiveTripModelTree::divesSelected(const QVector<dive *> &divesIn, dive *curr emit selectionChanged(indexes); // The current dive has changed. Transform the current dive into an index and pass it on to the view. - if (!current) { - emit currentDiveChanged(QModelIndex()); // No current dive -> tell view to clear current index with an invalid index - return; - } - - dive_trip *trip = current->divetrip; - if (!trip) { - // Outside of a trip - search top-level. - int idx = findDiveIdx(current); - if (idx < 0) { - // We don't know this dive. Something is wrong. Warn and bail. - qWarning() << "DiveTripModelTree::diveSelected(): unknown top-level dive"; - emit currentDiveChanged(QModelIndex()); - return; - } - emit currentDiveChanged(createIndex(idx, 0, noParent)); - } else { - int idx = findTripIdx(trip); - if (idx < 0) { - // We don't know the trip - this shouldn't happen. Warn and bail. - qWarning() << "DiveTripModelTree::diveSelected(): unknown trip"; - emit currentDiveChanged(QModelIndex()); - return; - } - int diveIdx = findDiveInTrip(idx, current); - if (diveIdx < 0) { - // We don't know this dive. Something is wrong. Warn and bail. - qWarning() << "DiveTripModelTree::diveSelected(): unknown dive"; - emit currentDiveChanged(QModelIndex()); - return; - } - emit currentDiveChanged(createIndex(diveIdx, 0, idx)); - } + currentChanged(); } void DiveTripModelTree::divesSelectedTrip(dive_trip *trip, const QVector<dive *> &dives, QVector<QModelIndex> &indexes) @@ -1327,6 +1365,9 @@ void DiveTripModelList::populate() continue; items.push_back(d); } + + // Remember the index of the current dive + oldCurrent = current_dive; } int DiveTripModelList::rowCount(const QModelIndex &parent) const @@ -1401,7 +1442,7 @@ void DiveTripModelList::addDives(QVector<dive *> &dives) }); } -void DiveTripModelList::removeDives(QVector<dive *> &dives) +void DiveTripModelList::removeDives(QVector<dive *> dives) { std::sort(dives.begin(), dives.end(), dive_less_than); processRangesZip(items, dives, @@ -1414,18 +1455,25 @@ void DiveTripModelList::removeDives(QVector<dive *> &dives) }); } -void DiveTripModelList::divesAdded(dive_trip *, bool, const QVector<dive *> &divesIn) +void DiveTripModelList::divesDeleted(dive_trip *trip, bool, const QVector<dive *> &divesIn) { QVector<dive *> dives = visibleDives(divesIn); - addDives(dives); + if (oldCurrent && std::find(dives.begin(), dives.end(), oldCurrent) != dives.end()) + oldCurrent = nullptr; + divesDeletedInternal(dives); } -void DiveTripModelList::divesDeleted(dive_trip *, bool, const QVector<dive *> &divesIn) +void DiveTripModelList::divesDeletedInternal(const QVector<dive *> &dives) { - QVector<dive *> dives = visibleDives(divesIn); removeDives(dives); } +void DiveTripModelList::divesAdded(dive_trip *, bool, const QVector<dive *> &divesIn) +{ + QVector<dive *> dives = visibleDives(divesIn); + addDives(dives); +} + void DiveTripModelList::diveSiteChanged(dive_site *ds, int field) { if (!isInterestingDiveSiteField(field)) @@ -1468,10 +1516,24 @@ void DiveTripModelList::divesTimeChanged(timestamp_t delta, const QVector<dive * std::sort(dives.begin(), dives.end(), dive_less_than); // See comment for DiveTripModelTree::divesTimeChanged above. - divesDeleted(nullptr, false, dives); + divesDeletedInternal(dives); // Use internal version to keep current dive divesAdded(nullptr, false, dives); } +QModelIndex DiveTripModelList::diveToIdx(const dive *d) const +{ + if (!d) + return QModelIndex(); + + auto it = std::find(items.begin(), items.end(), d); + if (it == items.end()) { + // We don't know this dive. Something is wrong. Warn and bail. + qWarning() << "DiveTripModelList::diveToIdx(): unknown dive"; + return QModelIndex(); + } + return createIndex(it - items.begin(), 0); +} + void DiveTripModelList::divesSelected(const QVector<dive *> &divesIn, dive *current) { QVector<dive *> dives = visibleDives(divesIn); @@ -1494,20 +1556,8 @@ void DiveTripModelList::divesSelected(const QVector<dive *> &divesIn, dive *curr emit selectionChanged(indexes); - // Transform the current dive into an index and pass it on to the view. - if (!current) { - emit currentDiveChanged(QModelIndex()); // No current dive -> tell view to clear current index with an invalid index - return; - } - - auto it = std::find(items.begin(), items.end(), current); - if (it == items.end()) { - // We don't know this dive. Something is wrong. Warn and bail. - qWarning() << "DiveTripModelList::divesSelected(): unknown dive"; - emit currentDiveChanged(QModelIndex()); - return; - } - emit currentDiveChanged(createIndex(it - items.begin(), 0)); + // The current dive has changed. Transform the current dive into an index and pass it on to the view. + currentChanged(); } // Simple sorting helper for sorting against a criterium and if diff --git a/qt-models/divetripmodel.h b/qt-models/divetripmodel.h index 64f89bd8d..132357b33 100644 --- a/qt-models/divetripmodel.h +++ b/qt-models/divetripmodel.h @@ -88,13 +88,17 @@ signals: void selectionChanged(const QVector<QModelIndex> &indexes); void currentDiveChanged(QModelIndex index); protected: + dive *oldCurrent; + // Access trip and dive data static QVariant diveData(const struct dive *d, int column, int role); static QVariant tripData(const dive_trip *trip, int column, int role); + void currentChanged(); virtual dive *diveOrNull(const QModelIndex &index) const = 0; // Returns a dive if this index represents a dive, null otherwise virtual void clearData() = 0; virtual void populate() = 0; + virtual QModelIndex diveToIdx(const dive *d) const = 0; }; class DiveTripModelTree : public DiveTripModelBase @@ -127,6 +131,7 @@ private: void divesShown(dive_trip *trip, const QVector<dive *> &dives); void divesHidden(dive_trip *trip, const QVector<dive *> &dives); void divesTimeChangedTrip(dive_trip *trip, timestamp_t delta, const QVector<dive *> &dives); + void divesDeletedInternal(dive_trip *trip, bool deleteTrip, const QVector<dive *> &dives); // The tree model has two levels. At the top level, we have either trips or dives // that do not belong to trips. Such a top-level item is represented by the "Item" @@ -163,6 +168,7 @@ private: // Access trips and dives int findTripIdx(const dive_trip *trip) const; int findDiveIdx(const dive *d) const; // Find _top_level_ dive + QModelIndex diveToIdx(const dive *d) const; // Find _any_ dive int findDiveInTrip(int tripIdx, const dive *d) const; // Find dive inside trip. Second parameter is index of trip int findInsertionIndex(const dive_trip *trip) const; // Where to insert trip @@ -196,7 +202,9 @@ private: bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const override; dive *diveOrNull(const QModelIndex &index) const override; void addDives(QVector<dive *> &dives); - void removeDives(QVector<dive *> &dives); + void removeDives(QVector<dive *> dives); + QModelIndex diveToIdx(const dive *d) const; + void divesDeletedInternal(const QVector<dive *> &dives); std::vector<dive *> items; // TODO: access core data directly }; |