diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2018-08-25 11:58:27 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-08-25 11:58:27 -0700 |
commit | eaf1bdbe5f810d2bd1fd45c489a33c3bd7fd4a51 (patch) | |
tree | 577953203debde33457a52ad11d0e5c5cf4425e7 | |
parent | 321a920a9873a3828a24c1b28cf8eb5fe1bff2cb (diff) | |
parent | 979f81f4090de1a4e828d2f6c1e5bc810d5e8b58 (diff) | |
download | subsurface-eaf1bdbe5f810d2bd1fd45c489a33c3bd7fd4a51.tar.gz |
Merge branch 'filter8' of https://github.com/bstoeger/subsurface
-rw-r--r-- | core/dive.c | 2 | ||||
-rw-r--r-- | qt-models/filtermodels.cpp | 96 | ||||
-rw-r--r-- | qt-models/filtermodels.h | 14 |
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; }; |