summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--commands/command_divelist.cpp18
-rw-r--r--core/divefilter.cpp39
-rw-r--r--core/divefilter.h20
-rw-r--r--qt-models/divetripmodel.cpp31
4 files changed, 63 insertions, 45 deletions
diff --git a/commands/command_divelist.cpp b/commands/command_divelist.cpp
index eedac4b6e..908b366a6 100644
--- a/commands/command_divelist.cpp
+++ b/commands/command_divelist.cpp
@@ -68,11 +68,9 @@ dive *DiveListBase::addDive(DiveToAdd &d)
}
dive *res = d.dive.release(); // Give up ownership of dive
- // Set the filter flag according to current filter settings
- bool show = DiveFilter::instance()->showDive(res);
- res->hidden_by_filter = !show;
- if (show)
- ++shown_dives;
+ // When we add dives, we start in hidden-by-filter status. Once all
+ // dives have been added, their status will be updated.
+ res->hidden_by_filter = true;
int idx = dive_table_get_insertion_index(&dive_table, res);
add_to_dive_table(&dive_table, idx, res); // Return ownership to backend
@@ -185,19 +183,21 @@ DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
[](const DiveToAdd &d, const DiveToAdd &d2)
{ return dive_less_than(d.dive.get(), d2.dive.get()); });
- // Remember old number of shown dives
- int oldShown = shown_dives;
-
// Now, add the dives
// Note: the idiomatic STL-way would be std::transform, but let's use a loop since
// that is closer to classical C-style.
auto it2 = res.rbegin();
+ QVector<dive *> divesToFilter;
+ divesToFilter.reserve(toAdd.dives.size());
for (auto it = toAdd.dives.rbegin(); it != toAdd.dives.rend(); ++it, ++it2) {
*it2 = addDive(*it);
dives.push_back({ (*it2)->divetrip, *it2 });
+ divesToFilter.push_back(*it2);
}
toAdd.dives.clear();
+ ShownChange change = DiveFilter::instance()->update(divesToFilter);
+
// If the dives belong to new trips, add these as well.
// Remember the pointers so that we can later check if a trip was newly added
std::vector<dive_trip *> addedTrips;
@@ -224,7 +224,7 @@ DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
emit diveListNotifier.divesAdded(trip, createTrip, divesInTrip);
});
- if (oldShown != shown_dives)
+ if (!change.newShown.empty() || !change.newHidden.empty())
emit diveListNotifier.numShownChanged();
return { res, sites };
diff --git a/core/divefilter.cpp b/core/divefilter.cpp
index 5bb05b947..7f47e45ac 100644
--- a/core/divefilter.cpp
+++ b/core/divefilter.cpp
@@ -8,10 +8,12 @@ DiveFilter::DiveFilter()
{
}
-bool DiveFilter::showDive(const struct dive *d) const
+ShownChange DiveFilter::update(const QVector<dive *> &) const
+{
+}
+
+ShownChange DiveFilter::updateAll() const
{
- // TODO: Do something useful
- return true;
}
#else // SUBSURFACE_MOBILE
@@ -24,6 +26,37 @@ bool DiveFilter::showDive(const struct dive *d) const
#include "core/divesite.h"
#include "qt-models/filtermodels.h"
+void DiveFilter::updateDiveStatus(dive *d, ShownChange &change) const
+{
+ bool newStatus = showDive(d);
+ if (filter_dive(d, newStatus)) {
+ if (newStatus)
+ change.newShown.push_back(d);
+ else
+ change.newHidden.push_back(d);
+ }
+}
+
+ShownChange DiveFilter::update(const QVector<dive *> &dives) const
+{
+ dive *old_current = current_dive;
+ ShownChange res;
+ for (dive *d: dives)
+ updateDiveStatus(d, res);
+ res.currentChanged = old_current != current_dive;
+ return res;
+}
+
+ShownChange DiveFilter::updateAll() const
+{
+ dive *old_current = current_dive;
+ ShownChange res;
+ for (int i = 0; i < dive_table.nr; ++i)
+ updateDiveStatus(get_dive(i), res);
+ res.currentChanged = old_current != current_dive;
+ return res;
+}
+
namespace {
// Pointer to function that takes two strings and returns whether
// the first matches the second according to a criterion (substring, starts-with, exact).
diff --git a/core/divefilter.h b/core/divefilter.h
index 2ad3c4b9b..aa166d022 100644
--- a/core/divefilter.h
+++ b/core/divefilter.h
@@ -3,6 +3,16 @@
#ifndef DIVE_FILTER_H
#define DIVE_FILTER_H
+#include <QVector>
+struct dive;
+
+// Structure describing changes of shown status upon applying the filter
+struct ShownChange {
+ QVector<dive *> newShown;
+ QVector<dive *> newHidden;
+ bool currentChanged;
+};
+
// The dive filter for mobile is currently much simpler than for desktop.
// Therefore, for now we have two completely separate implementations.
// This should be unified in the future.
@@ -12,7 +22,8 @@ class DiveFilter {
public:
static DiveFilter *instance();
- bool showDive(const struct dive *d) const;
+ ShownChange update(const QVector<dive *> &dives) const; // Update filter status of given dives and return dives whose status changed
+ ShownChange updateAll() const; // Update filter status of all dives and return dives whose status changed
private:
DiveFilter();
};
@@ -21,9 +32,7 @@ private:
#include <QDateTime>
#include <QStringList>
-#include <QVector>
-struct dive;
struct dive_trip;
struct dive_site;
@@ -82,15 +91,18 @@ class DiveFilter {
public:
static DiveFilter *instance();
- bool showDive(const struct dive *d) const;
bool diveSiteMode() const; // returns true if we're filtering on dive site
const QVector<dive_site *> &filteredDiveSites() const;
void startFilterDiveSites(QVector<dive_site *> ds);
void setFilterDiveSite(QVector<dive_site *> ds);
void stopFilterDiveSites();
void setFilter(const FilterData &data);
+ ShownChange update(const QVector<dive *> &dives) const; // Update filter status of given dives and return dives whose status changed
+ ShownChange updateAll() const; // Update filter status of all dives and return dives whose status changed
private:
DiveFilter();
+ void updateDiveStatus(dive *d, ShownChange &change) const;
+ bool showDive(const struct dive *d) const; // Should that dive be shown?
QVector<dive_site *> dive_sites;
FilterData filterData;
diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp
index e3b8266cf..ce4206cfb 100644
--- a/qt-models/divetripmodel.cpp
+++ b/qt-models/divetripmodel.cpp
@@ -432,41 +432,18 @@ bool DiveTripModelBase::setData(const QModelIndex &index, const QVariant &value,
return true;
}
-// Structure describing changes of shown status
-struct ShownChange {
- QVector<dive *> newShown;
- QVector<dive *> newHidden;
- bool currentChanged;
- void filterDive(dive *d, const DiveFilter *filter);
-};
-
-void ShownChange::filterDive(dive *d, const DiveFilter *filter)
-{
- bool newStatus = filter->showDive(d);
- if (filter_dive(d, newStatus)) {
- if (newStatus)
- newShown.push_back(d);
- else
- newHidden.push_back(d);
- }
-}
-
// Update visibility status of dive and return dives whose visibility changed.
// Attention: the changed dives are removed from the original vector!
static ShownChange updateShown(QVector<dive *> &dives)
{
DiveFilter *filter = DiveFilter::instance();
- dive *old_current = current_dive;
- ShownChange res;
- for (dive *d: dives)
- res.filterDive(d, filter);
+ ShownChange res = filter->update(dives);
if (!res.newShown.empty() || !res.newHidden.empty())
emit diveListNotifier.numShownChanged();
for (dive *d: res.newHidden)
dives.removeAll(d);
for (dive *d: res.newShown)
dives.removeAll(d);
- res.currentChanged = old_current != current_dive;
return res;
}
@@ -474,13 +451,9 @@ static ShownChange updateShown(QVector<dive *> &dives)
static ShownChange updateShownAll()
{
DiveFilter *filter = DiveFilter::instance();
- dive *old_current = current_dive;
- ShownChange res;
- for (int i = 0; i < dive_table.nr; ++i)
- res.filterDive(get_dive(i), filter);
+ ShownChange res = filter->updateAll();
if (!res.newShown.empty() || !res.newHidden.empty())
emit diveListNotifier.numShownChanged();
- res.currentChanged = old_current != current_dive;
return res;
}