mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
divetripmodel: use change of CURRENT_ROLE to propagate current dive
If compiled on mobile, on change of the current dive, don't send a signal, but send changed-event with the CURRENT_ROLE for both dives that changed status (previously selected and newly selected). Mobile does not use this yet, but will do so with the new flattened models. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
dbddec59d3
commit
b575a794ea
2 changed files with 116 additions and 58 deletions
|
@ -377,6 +377,7 @@ void DiveTripModelBase::clear()
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
clear_dive_file_data();
|
clear_dive_file_data();
|
||||||
clearData();
|
clearData();
|
||||||
|
oldCurrent = nullptr;
|
||||||
emit diveListNotifier.divesSelected({}, nullptr); // Inform profile, etc of changed selection
|
emit diveListNotifier.divesSelected({}, nullptr); // Inform profile, etc of changed selection
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
@ -459,6 +460,34 @@ static ShownChange updateShownAll()
|
||||||
return res;
|
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.
|
// Find a range of matching elements in a vector.
|
||||||
// Input parameters:
|
// Input parameters:
|
||||||
// v: vector to be searched
|
// v: vector to be searched
|
||||||
|
@ -627,6 +656,9 @@ void DiveTripModelTree::populate()
|
||||||
it->dives.push_back(d);
|
it->dives.push_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remember the index of the current dive
|
||||||
|
oldCurrent = current_dive;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DiveTripModelTree::rowCount(const QModelIndex &parent) const
|
int DiveTripModelTree::rowCount(const QModelIndex &parent) const
|
||||||
|
@ -1036,6 +1068,13 @@ void DiveTripModelTree::divesDeleted(dive_trip *trip, bool deleteTrip, const QVe
|
||||||
if (dives.empty())
|
if (dives.empty())
|
||||||
return;
|
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) {
|
if (!trip) {
|
||||||
// This is outside of a trip. Delete top-level dives in batches.
|
// This is outside of a trip. Delete top-level dives in batches.
|
||||||
removeDivesTopLevel(dives);
|
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.
|
// Unfortunately, removing the dives means that their selection is lost.
|
||||||
// Thus, remember the selection and re-add it later.
|
// Thus, remember the selection and re-add it later.
|
||||||
divesAdded(to, createTo, dives);
|
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)
|
void DiveTripModelTree::divesTimeChanged(timestamp_t delta, const QVector<dive *> &dives)
|
||||||
|
@ -1198,10 +1237,41 @@ void DiveTripModelTree::divesTimeChangedTrip(dive_trip *trip, timestamp_t delta,
|
||||||
// Cheating!
|
// Cheating!
|
||||||
// Unfortunately, removing the dives means that their selection is lost.
|
// Unfortunately, removing the dives means that their selection is lost.
|
||||||
// Thus, remember the selection and re-add it later.
|
// 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);
|
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)
|
void DiveTripModelTree::divesSelected(const QVector<dive *> &divesIn, dive *current)
|
||||||
{
|
{
|
||||||
QVector <dive *> dives = visibleDives(divesIn);
|
QVector <dive *> dives = visibleDives(divesIn);
|
||||||
|
@ -1219,39 +1289,7 @@ void DiveTripModelTree::divesSelected(const QVector<dive *> &divesIn, dive *curr
|
||||||
emit selectionChanged(indexes);
|
emit selectionChanged(indexes);
|
||||||
|
|
||||||
// The current dive has changed. Transform the current dive into an index and pass it on to the view.
|
// The current dive has changed. Transform the current dive into an index and pass it on to the view.
|
||||||
if (!current) {
|
currentChanged();
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveTripModelTree::divesSelectedTrip(dive_trip *trip, const QVector<dive *> &dives, QVector<QModelIndex> &indexes)
|
void DiveTripModelTree::divesSelectedTrip(dive_trip *trip, const QVector<dive *> &dives, QVector<QModelIndex> &indexes)
|
||||||
|
@ -1327,6 +1365,9 @@ void DiveTripModelList::populate()
|
||||||
continue;
|
continue;
|
||||||
items.push_back(d);
|
items.push_back(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remember the index of the current dive
|
||||||
|
oldCurrent = current_dive;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DiveTripModelList::rowCount(const QModelIndex &parent) const
|
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);
|
std::sort(dives.begin(), dives.end(), dive_less_than);
|
||||||
processRangesZip(items, dives,
|
processRangesZip(items, dives,
|
||||||
|
@ -1414,18 +1455,25 @@ void DiveTripModelList::removeDives(QVector<dive *> &dives)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiveTripModelList::divesDeleted(dive_trip *trip, bool, const QVector<dive *> &divesIn)
|
||||||
|
{
|
||||||
|
QVector<dive *> dives = visibleDives(divesIn);
|
||||||
|
if (oldCurrent && std::find(dives.begin(), dives.end(), oldCurrent) != dives.end())
|
||||||
|
oldCurrent = nullptr;
|
||||||
|
divesDeletedInternal(dives);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiveTripModelList::divesDeletedInternal(const QVector<dive *> &dives)
|
||||||
|
{
|
||||||
|
removeDives(dives);
|
||||||
|
}
|
||||||
|
|
||||||
void DiveTripModelList::divesAdded(dive_trip *, bool, const QVector<dive *> &divesIn)
|
void DiveTripModelList::divesAdded(dive_trip *, bool, const QVector<dive *> &divesIn)
|
||||||
{
|
{
|
||||||
QVector<dive *> dives = visibleDives(divesIn);
|
QVector<dive *> dives = visibleDives(divesIn);
|
||||||
addDives(dives);
|
addDives(dives);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveTripModelList::divesDeleted(dive_trip *, bool, const QVector<dive *> &divesIn)
|
|
||||||
{
|
|
||||||
QVector<dive *> dives = visibleDives(divesIn);
|
|
||||||
removeDives(dives);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiveTripModelList::diveSiteChanged(dive_site *ds, int field)
|
void DiveTripModelList::diveSiteChanged(dive_site *ds, int field)
|
||||||
{
|
{
|
||||||
if (!isInterestingDiveSiteField(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);
|
std::sort(dives.begin(), dives.end(), dive_less_than);
|
||||||
|
|
||||||
// See comment for DiveTripModelTree::divesTimeChanged above.
|
// See comment for DiveTripModelTree::divesTimeChanged above.
|
||||||
divesDeleted(nullptr, false, dives);
|
divesDeletedInternal(dives); // Use internal version to keep current dive
|
||||||
divesAdded(nullptr, false, dives);
|
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)
|
void DiveTripModelList::divesSelected(const QVector<dive *> &divesIn, dive *current)
|
||||||
{
|
{
|
||||||
QVector<dive *> dives = visibleDives(divesIn);
|
QVector<dive *> dives = visibleDives(divesIn);
|
||||||
|
@ -1494,20 +1556,8 @@ void DiveTripModelList::divesSelected(const QVector<dive *> &divesIn, dive *curr
|
||||||
|
|
||||||
emit selectionChanged(indexes);
|
emit selectionChanged(indexes);
|
||||||
|
|
||||||
// Transform the current dive into an index and pass it on to the view.
|
// The current dive has changed. Transform the current dive into an index and pass it on to the view.
|
||||||
if (!current) {
|
currentChanged();
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple sorting helper for sorting against a criterium and if
|
// Simple sorting helper for sorting against a criterium and if
|
||||||
|
|
|
@ -88,13 +88,17 @@ signals:
|
||||||
void selectionChanged(const QVector<QModelIndex> &indexes);
|
void selectionChanged(const QVector<QModelIndex> &indexes);
|
||||||
void currentDiveChanged(QModelIndex index);
|
void currentDiveChanged(QModelIndex index);
|
||||||
protected:
|
protected:
|
||||||
|
dive *oldCurrent;
|
||||||
|
|
||||||
// Access trip and dive data
|
// Access trip and dive data
|
||||||
static QVariant diveData(const struct dive *d, int column, int role);
|
static QVariant diveData(const struct dive *d, int column, int role);
|
||||||
static QVariant tripData(const dive_trip *trip, 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 dive *diveOrNull(const QModelIndex &index) const = 0; // Returns a dive if this index represents a dive, null otherwise
|
||||||
virtual void clearData() = 0;
|
virtual void clearData() = 0;
|
||||||
virtual void populate() = 0;
|
virtual void populate() = 0;
|
||||||
|
virtual QModelIndex diveToIdx(const dive *d) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiveTripModelTree : public DiveTripModelBase
|
class DiveTripModelTree : public DiveTripModelBase
|
||||||
|
@ -127,6 +131,7 @@ private:
|
||||||
void divesShown(dive_trip *trip, const QVector<dive *> &dives);
|
void divesShown(dive_trip *trip, const QVector<dive *> &dives);
|
||||||
void divesHidden(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 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
|
// 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"
|
// 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
|
// Access trips and dives
|
||||||
int findTripIdx(const dive_trip *trip) const;
|
int findTripIdx(const dive_trip *trip) const;
|
||||||
int findDiveIdx(const dive *d) const; // Find _top_level_ dive
|
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 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
|
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;
|
bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const override;
|
||||||
dive *diveOrNull(const QModelIndex &index) const override;
|
dive *diveOrNull(const QModelIndex &index) const override;
|
||||||
void addDives(QVector<dive *> &dives);
|
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
|
std::vector<dive *> items; // TODO: access core data directly
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue