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();
|
||||
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::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)
|
||||
{
|
||||
QVector<dive *> dives = visibleDives(divesIn);
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue