mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
e7063b6b08
commit
9afea37e15
4 changed files with 46 additions and 3 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "core/qthelper.h"
|
#include "core/qthelper.h"
|
||||||
#include "core/subsurface-string.h"
|
#include "core/subsurface-string.h"
|
||||||
#include "qt-models/divelocationmodel.h"
|
#include "qt-models/divelocationmodel.h"
|
||||||
|
#include "qt-models/filtermodels.h"
|
||||||
|
|
||||||
namespace Command {
|
namespace Command {
|
||||||
|
|
||||||
|
@ -17,13 +18,16 @@ namespace Command {
|
||||||
static std::vector<dive_site *> addDiveSites(std::vector<OwningDiveSitePtr> &sites)
|
static std::vector<dive_site *> addDiveSites(std::vector<OwningDiveSitePtr> &sites)
|
||||||
{
|
{
|
||||||
std::vector<dive_site *> res;
|
std::vector<dive_site *> res;
|
||||||
|
std::vector<dive *> changedDives;
|
||||||
res.reserve(sites.size());
|
res.reserve(sites.size());
|
||||||
|
|
||||||
for (OwningDiveSitePtr &ds: sites) {
|
for (OwningDiveSitePtr &ds: sites) {
|
||||||
// Readd the dives that belonged to this site
|
// Readd the dives that belonged to this site
|
||||||
for (int i = 0; i < ds->dives.nr; ++i) {
|
for (int i = 0; i < ds->dives.nr; ++i) {
|
||||||
// TODO: send dive site changed signal
|
// 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.
|
// 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.
|
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
|
// Clear vector of unused owning pointers
|
||||||
sites.clear();
|
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)
|
static std::vector<OwningDiveSitePtr> removeDiveSites(std::vector<dive_site *> &sites)
|
||||||
{
|
{
|
||||||
std::vector<OwningDiveSitePtr> res;
|
std::vector<OwningDiveSitePtr> res;
|
||||||
|
std::vector<dive *> changedDives;
|
||||||
res.reserve(sites.size());
|
res.reserve(sites.size());
|
||||||
|
|
||||||
for (dive_site *ds: sites) {
|
for (dive_site *ds: sites) {
|
||||||
// Reset the dive_site field of the affected dives
|
// Reset the dive_site field of the affected dives
|
||||||
for (int i = 0; i < ds->dives.nr; ++i) {
|
for (int i = 0; i < ds->dives.nr; ++i) {
|
||||||
// TODO: send dive site changed signal
|
struct dive *d = ds->dives.dives[i];
|
||||||
ds->dives.dives[i]->dive_site = nullptr;
|
d->dive_site = nullptr;
|
||||||
|
changedDives.push_back(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove dive site from core and take ownership.
|
// 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.
|
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();
|
sites.clear();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -344,6 +358,7 @@ void MergeDiveSites::undo()
|
||||||
}
|
}
|
||||||
|
|
||||||
sitesToRemove = std::move(addDiveSites(sitesToAdd));
|
sitesToRemove = std::move(addDiveSites(sitesToAdd));
|
||||||
|
|
||||||
processByTrip(divesChanged, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) {
|
processByTrip(divesChanged, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) {
|
||||||
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVESITE);
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVESITE);
|
||||||
});
|
});
|
||||||
|
|
|
@ -876,6 +876,12 @@ void DiveTripModelTree::divesDeleted(dive_trip *trip, bool deleteTrip, const QVe
|
||||||
|
|
||||||
void DiveTripModelTree::divesChanged(dive_trip *trip, const QVector<dive *> &dives)
|
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) {
|
if (!trip) {
|
||||||
// This is outside of a trip. Process top-level items range-wise.
|
// 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
|
// If necessary, move the trip
|
||||||
topLevelChanged(idx);
|
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)
|
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
|
// 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
|
// in dives as this must be the first that we encounter. Once we find a range, increase the
|
||||||
// index accordingly.
|
// index accordingly.
|
||||||
|
|
|
@ -249,6 +249,18 @@ void MultiFilterSortModel::myInvalidate()
|
||||||
#endif
|
#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()
|
void MultiFilterSortModel::clearFilter()
|
||||||
{
|
{
|
||||||
myInvalidate();
|
myInvalidate();
|
||||||
|
|
|
@ -60,6 +60,7 @@ public:
|
||||||
static MultiFilterSortModel *instance();
|
static MultiFilterSortModel *instance();
|
||||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||||
bool showDive(const struct dive *d) const;
|
bool showDive(const struct dive *d) const;
|
||||||
|
bool updateDive(struct dive *d); // returns true if visibility status changed
|
||||||
int divesDisplayed;
|
int divesDisplayed;
|
||||||
bool lessThan(const QModelIndex &, const QModelIndex &) const override;
|
bool lessThan(const QModelIndex &, const QModelIndex &) const override;
|
||||||
public
|
public
|
||||||
|
|
Loading…
Add table
Reference in a new issue