mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Filter: make tags, people and location filter logically-and
If the user provides multiple tags, they probably want to search for dive with *all* of these tags. Replace the convoluted loops by std::all_of(). This makes it trivial to change logically-and to logically-or: Replace std::all_of() by std::any_of(). Reported-by: Jan Mulder <jlmulder@xs4all.nl> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
f67f07223f
commit
8fa156eb0d
1 changed files with 34 additions and 43 deletions
|
@ -16,57 +16,48 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool hasTag(const QStringList tags, const struct dive *d)
|
// Check if a string-list contains at least one string containing the second argument.
|
||||||
|
// Comparison is non case sensitive and removes white space.
|
||||||
|
bool listContainsSuperstring(const QStringList &list, const QString &s)
|
||||||
{
|
{
|
||||||
if (!tags.isEmpty()) {
|
return std::any_of(list.begin(), list.end(), [&s](const QString &s2)
|
||||||
auto dive_tags = get_taglist_string(d->tag_list).split(",");
|
{ return s2.trimmed().contains(s.trimmed(), Qt::CaseInsensitive); });
|
||||||
bool found_tag = false;
|
|
||||||
for (const auto& filter_tag : tags)
|
|
||||||
for (const auto& dive_tag : dive_tags)
|
|
||||||
if (dive_tag.trimmed().toUpper().contains(filter_tag.trimmed().toUpper()))
|
|
||||||
found_tag = true;
|
|
||||||
|
|
||||||
return found_tag;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasPerson(const QStringList people, const struct dive *d)
|
bool hasTags(const QStringList &tags, const struct dive *d)
|
||||||
{
|
{
|
||||||
if (!people.isEmpty()) {
|
if (tags.isEmpty())
|
||||||
QStringList dive_people = QString(d->buddy).split(",", QString::SkipEmptyParts)
|
return true;
|
||||||
+ QString(d->divemaster).split(",", QString::SkipEmptyParts);
|
QStringList dive_tags = get_taglist_string(d->tag_list).split(",");
|
||||||
|
|
||||||
bool found_person = false;
|
return std::all_of(tags.begin(), tags.end(), [&dive_tags](const QString &tag)
|
||||||
for(const auto& filter_person : people)
|
{ return listContainsSuperstring(dive_tags, tag); });
|
||||||
for(const auto& dive_person : dive_people)
|
|
||||||
if (dive_person.trimmed().toUpper().contains(filter_person.trimmed().toUpper()))
|
|
||||||
found_person = true;
|
|
||||||
|
|
||||||
return found_person;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasLocation(const QStringList locations, const struct dive *d)
|
bool hasPersons(const QStringList &people, const struct dive *d)
|
||||||
{
|
{
|
||||||
if (!locations.isEmpty()) {
|
if (people.isEmpty())
|
||||||
QStringList diveLocations;
|
return true;
|
||||||
if (d->divetrip)
|
QStringList dive_people = QString(d->buddy).split(",", QString::SkipEmptyParts)
|
||||||
diveLocations.push_back(QString(d->divetrip->location));
|
+ QString(d->divemaster).split(",", QString::SkipEmptyParts);
|
||||||
|
|
||||||
if (d->dive_site)
|
return std::all_of(people.begin(), people.end(), [&dive_people](const QString &person)
|
||||||
diveLocations.push_back(QString(d->dive_site->name));
|
{ return listContainsSuperstring(dive_people, person); });
|
||||||
|
}
|
||||||
|
|
||||||
bool found_location = false;
|
bool hasLocations(const QStringList &locations, const struct dive *d)
|
||||||
for (const auto& filter_location : locations)
|
{
|
||||||
for (const auto& dive_location : diveLocations)
|
if (locations.isEmpty())
|
||||||
if (dive_location.trimmed().toUpper().contains(filter_location.trimmed().toUpper()))
|
return true;
|
||||||
found_location = true;
|
QStringList diveLocations;
|
||||||
|
if (d->divetrip)
|
||||||
|
diveLocations.push_back(QString(d->divetrip->location));
|
||||||
|
|
||||||
return found_location;
|
if (d->dive_site)
|
||||||
}
|
diveLocations.push_back(QString(d->dive_site->name));
|
||||||
return true;
|
|
||||||
|
return std::all_of(locations.begin(), locations.end(), [&diveLocations](const QString &location)
|
||||||
|
{ return listContainsSuperstring(diveLocations, location); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Finish this iimplementation.
|
// TODO: Finish this iimplementation.
|
||||||
|
@ -130,15 +121,15 @@ bool MultiFilterSortModel::showDive(const struct dive *d) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// tags.
|
// tags.
|
||||||
if (!hasTag(filterData.tags, d))
|
if (!hasTags(filterData.tags, d))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// people
|
// people
|
||||||
if (!hasPerson(filterData.people, d))
|
if (!hasPersons(filterData.people, d))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Location
|
// Location
|
||||||
if (!hasLocation(filterData.location, d))
|
if (!hasLocations(filterData.location, d))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!hasEquipment(filterData.equipment, d))
|
if (!hasEquipment(filterData.equipment, d))
|
||||||
|
|
Loading…
Add table
Reference in a new issue