summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-03-22 20:55:05 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-04-12 18:19:07 +0300
commit9afea37e15db29f59048d1bc2553838943ca1b62 (patch)
tree784c76adcc6da786c32254b2aa400631d68753b3
parente7063b6b08dff5c35436a5fb16fcf3f81717ca52 (diff)
downloadsubsurface-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.cpp21
-rw-r--r--qt-models/divetripmodel.cpp15
-rw-r--r--qt-models/filtermodels.cpp12
-rw-r--r--qt-models/filtermodels.h1
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