diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2017-12-24 14:35:59 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2017-12-26 13:08:49 -0800 |
commit | b6bf57a13b5e4d3dd469b0fa8790d341eb4f1304 (patch) | |
tree | e57922eee99f54276adec54d4f277c8f26e1d1ab /qt-models | |
parent | b86c70ab2ce91c46355a71008334aa6743caa1e6 (diff) | |
download | subsurface-b6bf57a13b5e4d3dd469b0fa8790d341eb4f1304.tar.gz |
Introduce negate-toggle buttons to filter lists
Introduce toggle buttons which mean "filter all dives except
those fulfilling the selected criteria".
The old code used to check for rowCount() == 0. This should never happen,
because there is always a row "empty field". This check was moved into
the preamble of the functions to seperate it from the actual logic.
Fixes #435
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'qt-models')
-rw-r--r-- | qt-models/filtermodels.cpp | 80 | ||||
-rw-r--r-- | qt-models/filtermodels.h | 5 |
2 files changed, 44 insertions, 41 deletions
diff --git a/qt-models/filtermodels.cpp b/qt-models/filtermodels.cpp index 004ff8493..48a2fd9b9 100644 --- a/qt-models/filtermodels.cpp +++ b/qt-models/filtermodels.cpp @@ -26,7 +26,8 @@ CREATE_INSTANCE_METHOD(SuitsFilterModel) CREATE_INSTANCE_METHOD(MultiFilterSortModel) FilterModelBase::FilterModelBase(QObject *parent) : QStringListModel(parent), - anyChecked(false) + anyChecked(false), + negate(false) { } @@ -115,6 +116,12 @@ void FilterModelBase::invertSelection() emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0)); } +void FilterModelBase::setNegate(bool negateParam) +{ + negate = negateParam; + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0)); +} + SuitsFilterModel::SuitsFilterModel(QObject *parent) : FilterModelBase(parent) { } @@ -129,28 +136,25 @@ bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel Q_UNUSED(index0); Q_UNUSED(sourceModel); - if (!anyChecked) { + // rowCount() == 0 should never happen, because we have the "no suits" row + // let's handle it gracefully anyway. + if (!anyChecked || rowCount() == 0) return true; - } // Checked means 'Show', Unchecked means 'Hide'. QString suit(d->suit); // only show empty suit dives if the user checked that. - if (suit.isEmpty()) { - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } + if (suit.isEmpty()) + return checkState[rowCount() - 1] != negate; // there is a suit selected QStringList suitList = stringList(); // Ignore last item, since this is the "Show Empty Tags" entry for (int i = 0; i < rowCount() - 1; i++) { if (checkState[i] && suit == suitList[i]) - return true; + return !negate; } - return false; + return negate; } void SuitsFilterModel::repopulate() @@ -200,18 +204,16 @@ bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel * Q_UNUSED(sourceModel); // If there's nothing checked, this should show everything - if (!anyChecked) { + // rowCount() == 0 should never happen, because we have the "no tags" row + // let's handle it gracefully anyway. + if (!anyChecked || rowCount() == 0) return true; - } + // Checked means 'Show', Unchecked means 'Hide'. struct tag_entry *head = d->tag_list; - if (!head) { // last tag means "Show empty tags"; - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } + if (!head) // last tag means "Show empty tags"; + return checkState[rowCount() - 1] != negate; // have at least one tag. QStringList tagList = stringList(); @@ -221,11 +223,11 @@ bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel * QString tagName(head->tag->name); int index = tagList.indexOf(tagName); if (checkState[index]) - return true; + return !negate; head = head->next; } } - return false; + return negate; } BuddyFilterModel::BuddyFilterModel(QObject *parent) : FilterModelBase(parent) @@ -243,30 +245,28 @@ bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel Q_UNUSED(sourceModel); // If there's nothing checked, this should show everything - if (!anyChecked) { + // rowCount() == 0 should never happen, because we have the "no tags" row + // let's handle it gracefully anyway. + if (!anyChecked || rowCount() == 0) return true; - } + // Checked means 'Show', Unchecked means 'Hide'. QString persons = QString(d->buddy) + "," + QString(d->divemaster); QStringList personsList = persons.split(',', QString::SkipEmptyParts); for (QString &s : personsList) s = s.trimmed(); // only show empty buddie dives if the user checked that. - if (personsList.isEmpty()) { - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } + if (personsList.isEmpty()) + return checkState[rowCount() - 1] != negate; // have at least one buddy QStringList buddyList = stringList(); // Ignore last item, since this is the "Show Empty Tags" entry for (int i = 0; i < rowCount() - 1; i++) { if (checkState[i] && personsList.contains(buddyList[i], Qt::CaseInsensitive)) - return true; + return !negate; } - return false; + return negate; } void BuddyFilterModel::repopulate() @@ -302,27 +302,25 @@ bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstrac Q_UNUSED(index0); Q_UNUSED(sourceModel); - if (!anyChecked) { + // rowCount() == 0 should never happen, because we have the "no location" row + // let's handle it gracefully anyway. + if (!anyChecked || rowCount() == 0) return true; - } + // Checked means 'Show', Unchecked means 'Hide'. QString location(get_dive_location(d)); // only show empty location dives if the user checked that. - if (location.isEmpty()) { - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } + if (location.isEmpty()) + return checkState[rowCount() - 1] != negate; // There is a location selected QStringList locationList = stringList(); // Ignore last item, since this is the "Show Empty Tags" entry for (int i = 0; i < rowCount() - 1; i++) { if (checkState[i] && location == locationList[i]) - return true; + return !negate; } - return false; + return negate; } void LocationFilterModel::repopulate() diff --git a/qt-models/filtermodels.h b/qt-models/filtermodels.h index 9db5e5a97..b866b68b2 100644 --- a/qt-models/filtermodels.h +++ b/qt-models/filtermodels.h @@ -8,6 +8,7 @@ #include <vector> class FilterModelBase : public QStringListModel { + Q_OBJECT public: virtual bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const = 0; void clearFilter(); @@ -15,6 +16,10 @@ public: void invertSelection(); std::vector<char> checkState; bool anyChecked; + bool negate; +public +slots: + void setNegate(bool negate); protected: explicit FilterModelBase(QObject *parent = 0); void updateList(const QStringList &new_list); |