summaryrefslogtreecommitdiffstats
path: root/qt-models
diff options
context:
space:
mode:
Diffstat (limited to 'qt-models')
-rw-r--r--qt-models/divetripmodel.cpp160
-rw-r--r--qt-models/divetripmodel.h10
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
};