diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-03-22 20:55:05 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-04-12 18:19:07 +0300 |
commit | 9afea37e15db29f59048d1bc2553838943ca1b62 (patch) | |
tree | 784c76adcc6da786c32254b2aa400631d68753b3 | |
parent | e7063b6b08dff5c35436a5fb16fcf3f81717ca52 (diff) | |
download | subsurface-9afea37e15db29f59048d1bc2553838943ca1b62.tar.gz |
Undo: update filter flag when dives change
The filter code is strange: it actually only checks the
dive->hidden_by_filter flag. Thus, before propagating the dive
changed signal, this flag has to be updated. Do this in the
DiveTripModel. Ultimately, this should be refactored.
Moreover, if the filter-flag changed notify the frontend
of a changed trip so that the trip is hidden / unhidden.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | desktop-widgets/command_divesite.cpp | 21 | ||||
-rw-r--r-- | qt-models/divetripmodel.cpp | 15 | ||||
-rw-r--r-- | qt-models/filtermodels.cpp | 12 | ||||
-rw-r--r-- | qt-models/filtermodels.h | 1 |
4 files changed, 46 insertions, 3 deletions
diff --git a/desktop-widgets/command_divesite.cpp b/desktop-widgets/command_divesite.cpp index 4f53b376e..e18a7f3c1 100644 --- a/desktop-widgets/command_divesite.cpp +++ b/desktop-widgets/command_divesite.cpp @@ -7,6 +7,7 @@ #include "core/qthelper.h" #include "core/subsurface-string.h" #include "qt-models/divelocationmodel.h" +#include "qt-models/filtermodels.h" namespace Command { @@ -17,13 +18,16 @@ namespace Command { static std::vector<dive_site *> addDiveSites(std::vector<OwningDiveSitePtr> &sites) { std::vector<dive_site *> res; + std::vector<dive *> changedDives; res.reserve(sites.size()); for (OwningDiveSitePtr &ds: sites) { // Readd the dives that belonged to this site for (int i = 0; i < ds->dives.nr; ++i) { // TODO: send dive site changed signal - ds->dives.dives[i]->dive_site = ds.get(); + struct dive *d = ds->dives.dives[i]; + d->dive_site = ds.get(); + changedDives.push_back(d); } // Add dive site to core, but remember a non-owning pointer first. @@ -32,6 +36,10 @@ static std::vector<dive_site *> addDiveSites(std::vector<OwningDiveSitePtr> &sit emit diveListNotifier.diveSiteAdded(res.back(), idx); // Inform frontend of new dive site. } + processByTrip(changedDives, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) { + emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVESITE); + }); + // Clear vector of unused owning pointers sites.clear(); @@ -44,13 +52,15 @@ static std::vector<dive_site *> addDiveSites(std::vector<OwningDiveSitePtr> &sit static std::vector<OwningDiveSitePtr> removeDiveSites(std::vector<dive_site *> &sites) { std::vector<OwningDiveSitePtr> res; + std::vector<dive *> changedDives; res.reserve(sites.size()); for (dive_site *ds: sites) { // Reset the dive_site field of the affected dives for (int i = 0; i < ds->dives.nr; ++i) { - // TODO: send dive site changed signal - ds->dives.dives[i]->dive_site = nullptr; + struct dive *d = ds->dives.dives[i]; + d->dive_site = nullptr; + changedDives.push_back(d); } // Remove dive site from core and take ownership. @@ -59,6 +69,10 @@ static std::vector<OwningDiveSitePtr> removeDiveSites(std::vector<dive_site *> & emit diveListNotifier.diveSiteDeleted(ds, idx); // Inform frontend of removed dive site. } + processByTrip(changedDives, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) { + emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVESITE); + }); + sites.clear(); return res; @@ -344,6 +358,7 @@ void MergeDiveSites::undo() } sitesToRemove = std::move(addDiveSites(sitesToAdd)); + processByTrip(divesChanged, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) { emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVESITE); }); diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 297dffc5d..d79290725 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -876,6 +876,12 @@ void DiveTripModelTree::divesDeleted(dive_trip *trip, bool deleteTrip, const QVe void DiveTripModelTree::divesChanged(dive_trip *trip, const QVector<dive *> &dives) { + // Update filter flags. TODO: The filter should update the flag by itself when + // recieving the signals below. + bool diveChanged = false; + for (dive *d: dives) + diveChanged |= MultiFilterSortModel::instance()->updateDive(d); + if (!trip) { // This is outside of a trip. Process top-level items range-wise. @@ -910,6 +916,10 @@ void DiveTripModelTree::divesChanged(dive_trip *trip, const QVector<dive *> &div // If necessary, move the trip topLevelChanged(idx); + + // If a dive changed, re-render the trip in the list [or actually make it (in)visible]. + if (diveChanged) + dataChanged(createIndex(idx, 0, noParent), createIndex(idx, 0, noParent)); } } @@ -1161,6 +1171,11 @@ void DiveTripModelList::divesDeleted(dive_trip *trip, bool deleteTrip, const QVe void DiveTripModelList::divesChanged(dive_trip *trip, const QVector<dive *> &dives) { + // Update filter flags. TODO: The filter should update the flag by itself when + // recieving the signals below. + for (dive *d: dives) + MultiFilterSortModel::instance()->updateDive(d); + // Since we know that the dive list is sorted, we will only ever search for the first element // in dives as this must be the first that we encounter. Once we find a range, increase the // index accordingly. diff --git a/qt-models/filtermodels.cpp b/qt-models/filtermodels.cpp index 5fd9ed1f7..a0c910244 100644 --- a/qt-models/filtermodels.cpp +++ b/qt-models/filtermodels.cpp @@ -249,6 +249,18 @@ void MultiFilterSortModel::myInvalidate() #endif } +bool MultiFilterSortModel::updateDive(struct dive *d) +{ + bool oldStatus = !d->hidden_by_filter; + bool newStatus = showDive(d); + bool changed = oldStatus != newStatus; + if (changed) { + filter_dive(d, newStatus); + divesDisplayed += newStatus - oldStatus; + } + return changed; +} + void MultiFilterSortModel::clearFilter() { myInvalidate(); diff --git a/qt-models/filtermodels.h b/qt-models/filtermodels.h index 3b3e14abc..6513788f2 100644 --- a/qt-models/filtermodels.h +++ b/qt-models/filtermodels.h @@ -60,6 +60,7 @@ public: static MultiFilterSortModel *instance(); bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; bool showDive(const struct dive *d) const; + bool updateDive(struct dive *d); // returns true if visibility status changed int divesDisplayed; bool lessThan(const QModelIndex &, const QModelIndex &) const override; public |