aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2018-08-25 11:58:27 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-08-25 11:58:27 -0700
commiteaf1bdbe5f810d2bd1fd45c489a33c3bd7fd4a51 (patch)
tree577953203debde33457a52ad11d0e5c5cf4425e7
parent321a920a9873a3828a24c1b28cf8eb5fe1bff2cb (diff)
parent979f81f4090de1a4e828d2f6c1e5bc810d5e8b58 (diff)
downloadsubsurface-eaf1bdbe5f810d2bd1fd45c489a33c3bd7fd4a51.tar.gz
Merge branch 'filter8' of https://github.com/bstoeger/subsurface
-rw-r--r--core/dive.c2
-rw-r--r--qt-models/filtermodels.cpp96
-rw-r--r--qt-models/filtermodels.h14
3 files changed, 53 insertions, 59 deletions
diff --git a/core/dive.c b/core/dive.c
index 535810901..044c969ee 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -4204,7 +4204,7 @@ const char *get_dive_country(const struct dive *dive)
const char *get_dive_location(const struct dive *dive)
{
- struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
+ const struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
if (ds && ds->name)
return ds->name;
return NULL;
diff --git a/qt-models/filtermodels.cpp b/qt-models/filtermodels.cpp
index 12d755dc1..1943056f7 100644
--- a/qt-models/filtermodels.cpp
+++ b/qt-models/filtermodels.cpp
@@ -132,7 +132,7 @@ int SuitsFilterModel::countDives(const char *s) const
return count_dives_with_suit(s);
}
-bool SuitsFilterModel::doFilter(dive *d, QModelIndex&, QAbstractItemModel*) const
+bool SuitsFilterModel::doFilter(const dive *d) const
{
// rowCount() == 0 should never happen, because we have the "no suits" row
// let's handle it gracefully anyway.
@@ -196,7 +196,7 @@ void TagFilterModel::repopulate()
updateList(list);
}
-bool TagFilterModel::doFilter(dive *d, QModelIndex&, QAbstractItemModel*) const
+bool TagFilterModel::doFilter(const dive *d) const
{
// If there's nothing checked, this should show everything
// rowCount() == 0 should never happen, because we have the "no tags" row
@@ -234,7 +234,7 @@ int BuddyFilterModel::countDives(const char *s) const
return count_dives_with_person(s);
}
-bool BuddyFilterModel::doFilter(dive *d, QModelIndex&, QAbstractItemModel*) const
+bool BuddyFilterModel::doFilter(const dive *d) const
{
// If there's nothing checked, this should show everything
// rowCount() == 0 should never happen, because we have the "no tags" row
@@ -289,7 +289,7 @@ int LocationFilterModel::countDives(const char *s) const
return count_dives_with_location(s);
}
-bool LocationFilterModel::doFilter(struct dive *d, QModelIndex&, QAbstractItemModel*) const
+bool LocationFilterModel::doFilter(const dive *d) const
{
// rowCount() == 0 should never happen, because we have the "no location" row
// let's handle it gracefully anyway.
@@ -362,62 +362,53 @@ void LocationFilterModel::addName(const QString &newName)
MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent),
divesDisplayed(0),
- justCleared(false),
curr_dive_site(NULL)
{
}
-bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+bool MultiFilterSortModel::showDive(const struct dive *d) const
{
- bool shouldShow = true;
- QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
- QVariant diveVariant = sourceModel()->data(index0, DiveTripModel::DIVE_ROLE);
- struct dive *d = (struct dive *)diveVariant.value<void *>();
-
if (curr_dive_site) {
- struct dive_site *ds = NULL;
- if (!d) { // It's a trip, only show the ones that have dives to be shown.
- bool showTrip = false;
- for (int i = 0; i < sourceModel()->rowCount(index0); i++) {
- QModelIndex child = sourceModel()->index(i, 0, index0);
- d = (struct dive *)sourceModel()->data(child, DiveTripModel::DIVE_ROLE).value<void *>();
- ds = get_dive_site_by_uuid(d->dive_site_uuid);
- if (!ds)
- continue;
- if (same_string(ds->name, curr_dive_site->name) || ds->uuid == curr_dive_site->uuid) {
- if (ds->uuid != curr_dive_site->uuid) {
- qWarning() << "Warning, two different dive sites with same name have a different id"
- << ds->uuid << "and" << curr_dive_site->uuid;
- }
- showTrip = true; // do not shortcircuit the loop or the counts will be wrong
- }
- }
- return showTrip;
- }
- ds = get_dive_site_by_uuid(d->dive_site_uuid);
+ dive_site *ds = get_dive_site_by_uuid(d->dive_site_uuid);
if (!ds)
return false;
return same_string(ds->name, curr_dive_site->name) || ds->uuid == curr_dive_site->uuid;
}
- if (justCleared || models.isEmpty())
+ if (models.isEmpty())
return true;
- if (!d) { // It's a trip, only show the ones that have dives to be shown.
- bool showTrip = false;
- for (int i = 0; i < sourceModel()->rowCount(index0); i++) {
- if (filterAcceptsRow(i, index0))
- showTrip = true; // do not shortcircuit the loop or the counts will be wrong
- }
- return showTrip;
- }
- Q_FOREACH (FilterModelBase *model, models) {
- if (!model->doFilter(d, index0, sourceModel()))
- shouldShow = false;
+ for (const FilterModelBase *model: models) {
+ if (!model->doFilter(d))
+ return false;
}
- filter_dive(d, shouldShow);
- return shouldShow;
+ return true;
+}
+
+bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+{
+ QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
+ QVariant diveVariant = sourceModel()->data(index0, DiveTripModel::DIVE_ROLE);
+ struct dive *d = (struct dive *)diveVariant.value<void *>();
+
+ // For dives, simply check the hidden_by_filter flag
+ if (d)
+ return !d->hidden_by_filter;
+
+ // Since this is not a dive, it must be a trip
+ QVariant tripVariant = sourceModel()->data(index0, DiveTripModel::TRIP_ROLE);
+ dive_trip *trip = (dive_trip *)tripVariant.value<void *>();
+
+ if (!trip)
+ return false; // Oops. Neither dive nor trip, something is seriously wrong.
+
+ // Show the trip if any dive is visible
+ for (d = trip->dives; d; d = d->next) {
+ if (!d->hidden_by_filter)
+ return true;
+ }
+ return false;
}
void MultiFilterSortModel::myInvalidate()
@@ -429,6 +420,14 @@ void MultiFilterSortModel::myInvalidate()
divesDisplayed = 0;
+ // Apply filter for each dive
+ for_each_dive (i, d) {
+ bool show = showDive(d);
+ filter_dive(d, show);
+ if (show)
+ divesDisplayed++;
+ }
+
invalidateFilter();
// first make sure the trips are no longer shown as selected
@@ -453,11 +452,6 @@ void MultiFilterSortModel::myInvalidate()
dlv->selectDives(curSelectedDives);
}
- for_each_dive (i, d) {
- if (!d->hidden_by_filter)
- divesDisplayed++;
- }
-
emit filterFinished();
if (curr_dive_site) {
@@ -480,11 +474,9 @@ void MultiFilterSortModel::removeFilterModel(FilterModelBase *model)
void MultiFilterSortModel::clearFilter()
{
- justCleared = true;
Q_FOREACH (FilterModelBase *iface, models) {
iface->clearFilter();
}
- justCleared = false;
myInvalidate();
}
diff --git a/qt-models/filtermodels.h b/qt-models/filtermodels.h
index 1d950e735..bcbbf000a 100644
--- a/qt-models/filtermodels.h
+++ b/qt-models/filtermodels.h
@@ -7,10 +7,12 @@
#include <stdint.h>
#include <vector>
+struct dive;
+
class FilterModelBase : public QStringListModel {
Q_OBJECT
public:
- virtual bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const = 0;
+ virtual bool doFilter(const dive *d) const = 0;
void clearFilter();
void selectAll();
void invertSelection();
@@ -34,7 +36,7 @@ class TagFilterModel : public FilterModelBase {
Q_OBJECT
public:
static TagFilterModel *instance();
- bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
+ bool doFilter(const dive *d) const;
public
slots:
void repopulate();
@@ -48,7 +50,7 @@ class BuddyFilterModel : public FilterModelBase {
Q_OBJECT
public:
static BuddyFilterModel *instance();
- bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
+ bool doFilter(const dive *d) const;
public
slots:
void repopulate();
@@ -62,7 +64,7 @@ class LocationFilterModel : public FilterModelBase {
Q_OBJECT
public:
static LocationFilterModel *instance();
- bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
+ bool doFilter(const dive *d) const;
public
slots:
void repopulate();
@@ -78,7 +80,7 @@ class SuitsFilterModel : public FilterModelBase {
Q_OBJECT
public:
static SuitsFilterModel *instance();
- bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
+ bool doFilter(const dive *d) const;
public
slots:
void repopulate();
@@ -95,6 +97,7 @@ public:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
void addFilterModel(FilterModelBase *model);
void removeFilterModel(FilterModelBase *model);
+ bool showDive(const struct dive *d) const;
int divesDisplayed;
public
slots:
@@ -108,7 +111,6 @@ signals:
private:
MultiFilterSortModel(QObject *parent = 0);
QList<FilterModelBase *> models;
- bool justCleared;
struct dive_site *curr_dive_site;
};