mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Filter: quick implementation of negation
Add negate buttons to the Tags, People, Location and Equipment filters. Currently, if nothing is entered the filter is ignored whether negate is on or off. One might think about filtering all dives without tags, etc. instead. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
c383079626
commit
de4e6792c6
4 changed files with 81 additions and 33 deletions
|
@ -20,8 +20,8 @@ FilterWidget2::FilterWidget2(QWidget* parent) : QWidget(parent), ignoreSignal(fa
|
|||
|
||||
// TODO: unhide this when we discover how to search for equipment.
|
||||
ui.equipment->hide();
|
||||
ui.equipmentNegate->hide();
|
||||
ui.labelEquipment->hide();
|
||||
ui.invertFilter->hide();
|
||||
|
||||
ui.fromDate->setDisplayFormat(prefs.date_format);
|
||||
ui.fromTime->setDisplayFormat(prefs.time_format);
|
||||
|
@ -77,12 +77,21 @@ FilterWidget2::FilterWidget2(QWidget* parent) : QWidget(parent), ignoreSignal(fa
|
|||
connect(ui.tags, &QLineEdit::textChanged,
|
||||
this, &FilterWidget2::updateFilter);
|
||||
|
||||
connect(ui.tagsNegate, &QToolButton::toggled,
|
||||
this, &FilterWidget2::updateFilter);
|
||||
|
||||
connect(ui.people, &QLineEdit::textChanged,
|
||||
this, &FilterWidget2::updateFilter);
|
||||
|
||||
connect(ui.peopleNegate, &QToolButton::toggled,
|
||||
this, &FilterWidget2::updateFilter);
|
||||
|
||||
connect(ui.location, &QLineEdit::textChanged,
|
||||
this, &FilterWidget2::updateFilter);
|
||||
|
||||
connect(ui.locationNegate, &QToolButton::toggled,
|
||||
this, &FilterWidget2::updateFilter);
|
||||
|
||||
connect(ui.logged, SIGNAL(stateChanged(int)), this, SLOT(updateLogged(int)));
|
||||
|
||||
connect(ui.planned, SIGNAL(stateChanged(int)), this, SLOT(updatePlanned(int)));
|
||||
|
@ -121,6 +130,10 @@ void FilterWidget2::clearFilter()
|
|||
ui.fromTime->setTime(filterData.fromTime);
|
||||
ui.toDate->setDate(filterData.toDate.date());
|
||||
ui.toTime->setTime(filterData.toTime);
|
||||
ui.tagsNegate->setChecked(filterData.tagsNegate);
|
||||
ui.peopleNegate->setChecked(filterData.peopleNegate);
|
||||
ui.locationNegate->setChecked(filterData.locationNegate);
|
||||
ui.equipmentNegate->setChecked(filterData.equipmentNegate);
|
||||
ignoreSignal = false;
|
||||
|
||||
filterDataChanged(filterData);
|
||||
|
@ -162,7 +175,10 @@ void FilterWidget2::updateFilter()
|
|||
filterData.people = ui.people->text().split(",", QString::SkipEmptyParts);
|
||||
filterData.location = ui.location->text().split(",", QString::SkipEmptyParts);
|
||||
filterData.equipment = ui.equipment->text().split(",", QString::SkipEmptyParts);
|
||||
filterData.invertFilter = ui.invertFilter->isChecked();
|
||||
filterData.tagsNegate = ui.tagsNegate->isChecked();
|
||||
filterData.peopleNegate = ui.peopleNegate->isChecked();
|
||||
filterData.locationNegate = ui.locationNegate->isChecked();
|
||||
filterData.equipmentNegate = ui.equipmentNegate->isChecked();
|
||||
filterData.logged = ui.logged->isChecked();
|
||||
filterData.planned = ui.planned->isChecked();
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2" colspan="7">
|
||||
<item row="8" column="2" colspan="6">
|
||||
<widget class="QLineEdit" name="tags"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
|
@ -62,16 +62,6 @@
|
|||
<item row="3" column="6">
|
||||
<widget class="QDoubleSpinBox" name="minWaterTemp"/>
|
||||
</item>
|
||||
<item row="12" column="2" colspan="7">
|
||||
<widget class="QCheckBox" name="invertFilter">
|
||||
<property name="toolTip">
|
||||
<string>Display dives that will not match the search, only applies to tags, people, location and equipment</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invert filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
|
@ -131,7 +121,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2" colspan="7">
|
||||
<item row="10" column="2" colspan="6">
|
||||
<widget class="QLineEdit" name="location"/>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
|
@ -147,7 +137,7 @@
|
|||
<item row="4" column="8">
|
||||
<widget class="QDoubleSpinBox" name="maxAirTemp"/>
|
||||
</item>
|
||||
<item row="11" column="2" colspan="7">
|
||||
<item row="11" column="2" colspan="6">
|
||||
<widget class="QLineEdit" name="equipment"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
|
@ -157,7 +147,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2" colspan="7">
|
||||
<item row="9" column="2" colspan="6">
|
||||
<widget class="QLineEdit" name="people"/>
|
||||
</item>
|
||||
<item row="4" column="7">
|
||||
|
@ -301,6 +291,46 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="8">
|
||||
<widget class="QToolButton" name="tagsNegate">
|
||||
<property name="text">
|
||||
<string>¬</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="8">
|
||||
<widget class="QToolButton" name="peopleNegate">
|
||||
<property name="text">
|
||||
<string>¬</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="8">
|
||||
<widget class="QToolButton" name="locationNegate">
|
||||
<property name="text">
|
||||
<string>¬</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="8">
|
||||
<widget class="QToolButton" name="equipmentNegate">
|
||||
<property name="text">
|
||||
<string>¬</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
@ -326,7 +356,6 @@
|
|||
<tabstop>people</tabstop>
|
||||
<tabstop>location</tabstop>
|
||||
<tabstop>equipment</tabstop>
|
||||
<tabstop>invertFilter</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -21,31 +21,31 @@ namespace {
|
|||
bool listContainsSuperstring(const QStringList &list, const QString &s)
|
||||
{
|
||||
return std::any_of(list.begin(), list.end(), [&s](const QString &s2)
|
||||
{ return s2.trimmed().contains(s.trimmed(), Qt::CaseInsensitive); });
|
||||
{ return s2.trimmed().contains(s.trimmed(), Qt::CaseInsensitive); } );
|
||||
}
|
||||
|
||||
bool hasTags(const QStringList &tags, const struct dive *d)
|
||||
bool hasTags(const QStringList &tags, const struct dive *d, bool negate)
|
||||
{
|
||||
if (tags.isEmpty())
|
||||
return true;
|
||||
QStringList dive_tags = get_taglist_string(d->tag_list).split(",");
|
||||
|
||||
return std::all_of(tags.begin(), tags.end(), [&dive_tags](const QString &tag)
|
||||
{ return listContainsSuperstring(dive_tags, tag); });
|
||||
return std::all_of(tags.begin(), tags.end(), [&dive_tags, negate](const QString &tag)
|
||||
{ return listContainsSuperstring(dive_tags, tag) != negate; } );
|
||||
}
|
||||
|
||||
bool hasPersons(const QStringList &people, const struct dive *d)
|
||||
bool hasPersons(const QStringList &people, const struct dive *d, bool negate)
|
||||
{
|
||||
if (people.isEmpty())
|
||||
return true;
|
||||
QStringList dive_people = QString(d->buddy).split(",", QString::SkipEmptyParts)
|
||||
+ QString(d->divemaster).split(",", QString::SkipEmptyParts);
|
||||
|
||||
return std::all_of(people.begin(), people.end(), [&dive_people](const QString &person)
|
||||
{ return listContainsSuperstring(dive_people, person); });
|
||||
return std::all_of(people.begin(), people.end(), [&dive_people, negate](const QString &person)
|
||||
{ return listContainsSuperstring(dive_people, person) != negate; } );
|
||||
}
|
||||
|
||||
bool hasLocations(const QStringList &locations, const struct dive *d)
|
||||
bool hasLocations(const QStringList &locations, const struct dive *d, bool negate)
|
||||
{
|
||||
if (locations.isEmpty())
|
||||
return true;
|
||||
|
@ -56,12 +56,12 @@ namespace {
|
|||
if (d->dive_site)
|
||||
diveLocations.push_back(QString(d->dive_site->name));
|
||||
|
||||
return std::all_of(locations.begin(), locations.end(), [&diveLocations](const QString &location)
|
||||
{ return listContainsSuperstring(diveLocations, location); });
|
||||
return std::all_of(locations.begin(), locations.end(), [&diveLocations, negate](const QString &location)
|
||||
{ return listContainsSuperstring(diveLocations, location) != negate; } );
|
||||
}
|
||||
|
||||
// TODO: Finish this iimplementation.
|
||||
bool hasEquipment(const QStringList& equipment, const struct dive *d)
|
||||
bool hasEquipment(const QStringList &, const struct dive *, bool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -129,18 +129,18 @@ bool MultiFilterSortModel::showDive(const struct dive *d) const
|
|||
return false;
|
||||
|
||||
// tags.
|
||||
if (!hasTags(filterData.tags, d))
|
||||
if (!hasTags(filterData.tags, d, filterData.tagsNegate))
|
||||
return false;
|
||||
|
||||
// people
|
||||
if (!hasPersons(filterData.people, d))
|
||||
if (!hasPersons(filterData.people, d, filterData.peopleNegate))
|
||||
return false;
|
||||
|
||||
// Location
|
||||
if (!hasLocations(filterData.location, d))
|
||||
if (!hasLocations(filterData.location, d, filterData.locationNegate))
|
||||
return false;
|
||||
|
||||
if (!hasEquipment(filterData.equipment, d))
|
||||
if (!hasEquipment(filterData.equipment, d, filterData.equipmentNegate))
|
||||
return false;
|
||||
|
||||
// Planned/Logged
|
||||
|
|
|
@ -35,9 +35,12 @@ struct FilterData {
|
|||
QStringList people;
|
||||
QStringList location;
|
||||
QStringList equipment;
|
||||
bool tagsNegate = false;
|
||||
bool peopleNegate = false;
|
||||
bool locationNegate = false;
|
||||
bool equipmentNegate = false;
|
||||
bool logged = true;
|
||||
bool planned = true;
|
||||
bool invertFilter;
|
||||
};
|
||||
|
||||
class MultiFilterSortModel : public QSortFilterProxyModel {
|
||||
|
|
Loading…
Add table
Reference in a new issue