summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2020-02-10 22:55:09 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2020-02-11 20:29:05 -0800
commita07d8cf5ea0179f3e99e73feb4a04533d7940e55 (patch)
tree1ea4459c874f7caf0b55e045c9dd15351092fe72
parentb3f0fd3e1894ab987be268726abca5ec2ebaeaf9 (diff)
downloadsubsurface-a07d8cf5ea0179f3e99e73feb4a04533d7940e55.tar.gz
Filter: implement starts-with and exact modes
Currently, we do substring search. Implement starts-with and exact mode (for example when search for "Cave vs. Cavern" tags). For each textual search criterion add a combo-box. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--CHANGELOG.md1
-rw-r--r--core/divefilter.cpp58
-rw-r--r--core/divefilter.h11
-rw-r--r--desktop-widgets/filterwidget2.cpp13
-rw-r--r--desktop-widgets/filterwidget2.ui454
5 files changed, 343 insertions, 194 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a40d7b4b..8b8903799 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+Desktop: add starts-with and exact filter modes for textual search
Mobile: add option to only show one column in portrait mode
Mobile: fix potential crash when adding / editing dives
Mobile: automatically scroll the dive edit screen so that the notes edit cursor stays visible
diff --git a/core/divefilter.cpp b/core/divefilter.cpp
index 595b5136c..5bb05b947 100644
--- a/core/divefilter.cpp
+++ b/core/divefilter.cpp
@@ -25,46 +25,57 @@ bool DiveFilter::showDive(const struct dive *d) const
#include "qt-models/filtermodels.h"
namespace {
+ // Pointer to function that takes two strings and returns whether
+ // the first matches the second according to a criterion (substring, starts-with, exact).
+ using StrCheck = bool (*) (const QString &s1, const QString &s2);
+
// 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)
+ bool listContainsSuperstring(const QStringList &list, const QString &s, StrCheck strchk)
{
- return std::any_of(list.begin(), list.end(), [&s](const QString &s2)
- { return s2.trimmed().contains(s.trimmed(), Qt::CaseInsensitive); } );
+ return std::any_of(list.begin(), list.end(), [&s,strchk](const QString &s2)
+ { return strchk(s2, s); } );
}
// Check whether either all, any or none of the items of the first list is
// in the second list as a super string.
// The mode is controlled by the second argument
- bool check(const QStringList &items, const QStringList &list, FilterData::Mode mode)
+ bool check(const QStringList &items, const QStringList &list, FilterData::Mode mode, FilterData::StringMode stringMode)
{
bool negate = mode == FilterData::Mode::NONE_OF;
bool any_of = mode == FilterData::Mode::ANY_OF;
- auto fun = [&list, negate](const QString &item)
- { return listContainsSuperstring(list, item) != negate; };
+ StrCheck strchk =
+ stringMode == FilterData::StringMode::SUBSTRING ?
+ [](const QString &s1, const QString &s2) { return s1.contains(s2, Qt::CaseInsensitive); } :
+ stringMode == FilterData::StringMode::STARTSWITH ?
+ [](const QString &s1, const QString &s2) { return s1.startsWith(s2, Qt::CaseInsensitive); } :
+ /* FilterData::StringMode::EXACT */
+ [](const QString &s1, const QString &s2) { return s1.compare(s2, Qt::CaseInsensitive) == 0; };
+ auto fun = [&list, negate, strchk](const QString &item)
+ { return listContainsSuperstring(list, item, strchk) != negate; };
return any_of ? std::any_of(items.begin(), items.end(), fun)
: std::all_of(items.begin(), items.end(), fun);
}
- bool hasTags(const QStringList &tags, const struct dive *d, FilterData::Mode mode)
+ bool hasTags(const QStringList &tags, const struct dive *d, FilterData::Mode mode, FilterData::StringMode stringMode)
{
if (tags.isEmpty())
return true;
QStringList dive_tags = get_taglist_string(d->tag_list).split(",");
dive_tags.append(gettextFromC::tr(divemode_text_ui[d->dc.divemode]));
- return check(tags, dive_tags, mode);
+ return check(tags, dive_tags, mode, stringMode);
}
- bool hasPersons(const QStringList &people, const struct dive *d, FilterData::Mode mode)
+ bool hasPersons(const QStringList &people, const struct dive *d, FilterData::Mode mode, FilterData::StringMode stringMode)
{
if (people.isEmpty())
return true;
QStringList dive_people = QString(d->buddy).split(",", QString::SkipEmptyParts)
+ QString(d->divemaster).split(",", QString::SkipEmptyParts);
- return check(people, dive_people, mode);
+ return check(people, dive_people, mode, stringMode);
}
- bool hasLocations(const QStringList &locations, const struct dive *d, FilterData::Mode mode)
+ bool hasLocations(const QStringList &locations, const struct dive *d, FilterData::Mode mode, FilterData::StringMode stringMode)
{
if (locations.isEmpty())
return true;
@@ -75,35 +86,34 @@ namespace {
if (d->dive_site)
diveLocations.push_back(QString(d->dive_site->name));
- return check(locations, diveLocations, mode);
+ return check(locations, diveLocations, mode, stringMode);
}
// TODO: Finish this implementation.
- bool hasEquipment(const QStringList &, const struct dive *, FilterData::Mode)
+ bool hasEquipment(const QStringList &, const struct dive *, FilterData::Mode, FilterData::StringMode)
{
return true;
}
- bool hasSuits(const QStringList &suits, const struct dive *d, FilterData::Mode mode)
+ bool hasSuits(const QStringList &suits, const struct dive *d, FilterData::Mode mode, FilterData::StringMode stringMode)
{
if (suits.isEmpty())
return true;
QStringList diveSuits;
if (d->suit)
diveSuits.push_back(QString(d->suit));
- return check(suits, diveSuits, mode);
+ return check(suits, diveSuits, mode, stringMode);
}
- bool hasNotes(const QStringList &dnotes, const struct dive *d, FilterData::Mode mode)
+ bool hasNotes(const QStringList &dnotes, const struct dive *d, FilterData::Mode mode, FilterData::StringMode stringMode)
{
if (dnotes.isEmpty())
return true;
QStringList diveNotes;
if (d->notes)
diveNotes.push_back(QString(d->notes));
- return check(dnotes, diveNotes, mode);
+ return check(dnotes, diveNotes, mode, stringMode);
}
-
}
DiveFilter *DiveFilter::instance()
@@ -152,26 +162,26 @@ bool DiveFilter::showDive(const struct dive *d) const
return false;
// tags.
- if (!hasTags(filterData.tags, d, filterData.tagsMode))
+ if (!hasTags(filterData.tags, d, filterData.tagsMode, filterData.tagsStringMode))
return false;
// people
- if (!hasPersons(filterData.people, d, filterData.peopleMode))
+ if (!hasPersons(filterData.people, d, filterData.peopleMode, filterData.peopleStringMode))
return false;
// Location
- if (!hasLocations(filterData.location, d, filterData.locationMode))
+ if (!hasLocations(filterData.location, d, filterData.locationMode, filterData.locationStringMode))
return false;
// Suit
- if (!hasSuits(filterData.suit, d, filterData.suitMode))
+ if (!hasSuits(filterData.suit, d, filterData.suitMode, filterData.suitStringMode))
return false;
// Notes
- if (!hasNotes(filterData.dnotes, d, filterData.dnotesMode))
+ if (!hasNotes(filterData.dnotes, d, filterData.dnotesMode, filterData.dnotesStringMode))
return false;
- if (!hasEquipment(filterData.equipment, d, filterData.equipmentMode))
+ if (!hasEquipment(filterData.equipment, d, filterData.equipmentMode, filterData.equipmentStringMode))
return false;
// Planned/Logged
diff --git a/core/divefilter.h b/core/divefilter.h
index 7435289bd..2ad3c4b9b 100644
--- a/core/divefilter.h
+++ b/core/divefilter.h
@@ -34,6 +34,11 @@ struct FilterData {
ANY_OF = 1,
NONE_OF = 2
};
+ enum class StringMode {
+ SUBSTRING = 0,
+ STARTSWITH = 1,
+ EXACT = 2
+ };
bool validFilter = false;
int minVisibility = 0;
@@ -63,6 +68,12 @@ struct FilterData {
Mode dnotesMode = Mode::ALL_OF;
Mode suitMode = Mode::ANY_OF;
Mode equipmentMode = Mode::ALL_OF;
+ StringMode tagsStringMode = StringMode::SUBSTRING;
+ StringMode peopleStringMode = StringMode::SUBSTRING;
+ StringMode locationStringMode = StringMode::SUBSTRING;
+ StringMode dnotesStringMode = StringMode::SUBSTRING;
+ StringMode suitStringMode = StringMode::SUBSTRING;
+ StringMode equipmentStringMode = StringMode::SUBSTRING;
bool logged = true;
bool planned = true;
};
diff --git a/desktop-widgets/filterwidget2.cpp b/desktop-widgets/filterwidget2.cpp
index 140016a03..da20fc45c 100644
--- a/desktop-widgets/filterwidget2.cpp
+++ b/desktop-widgets/filterwidget2.cpp
@@ -24,6 +24,7 @@ FilterWidget2::FilterWidget2(QWidget* parent) :
// TODO: unhide this when we discover how to search for equipment.
ui.equipment->hide();
ui.equipmentMode->hide();
+ ui.equipmentStringMode->hide();
ui.labelEquipment->hide();
ui.fromDate->setDisplayFormat(prefs.date_format);
@@ -154,6 +155,12 @@ void FilterWidget2::clearFilter()
ui.suitMode->setCurrentIndex((int)filterData.suitMode);
ui.dnotesMode->setCurrentIndex((int)filterData.dnotesMode);
ui.equipmentMode->setCurrentIndex((int)filterData.equipmentMode);
+ ui.tagsStringMode->setCurrentIndex((int)filterData.tagsStringMode);
+ ui.peopleStringMode->setCurrentIndex((int)filterData.peopleStringMode);
+ ui.locationStringMode->setCurrentIndex((int)filterData.locationStringMode);
+ ui.suitStringMode->setCurrentIndex((int)filterData.suitStringMode);
+ ui.dnotesStringMode->setCurrentIndex((int)filterData.dnotesStringMode);
+ ui.equipmentStringMode->setCurrentIndex((int)filterData.equipmentStringMode);
ignoreSignal = false;
@@ -204,6 +211,12 @@ void FilterWidget2::updateFilter()
filterData.suitMode = (FilterData::Mode)ui.suitMode->currentIndex();
filterData.dnotesMode = (FilterData::Mode)ui.dnotesMode->currentIndex();
filterData.equipmentMode = (FilterData::Mode)ui.equipmentMode->currentIndex();
+ filterData.tagsStringMode = (FilterData::StringMode)ui.tagsStringMode->currentIndex();
+ filterData.peopleStringMode = (FilterData::StringMode)ui.peopleStringMode->currentIndex();
+ filterData.locationStringMode = (FilterData::StringMode)ui.locationStringMode->currentIndex();
+ filterData.suitStringMode = (FilterData::StringMode)ui.suitStringMode->currentIndex();
+ filterData.dnotesStringMode = (FilterData::StringMode)ui.dnotesStringMode->currentIndex();
+ filterData.equipmentStringMode = (FilterData::StringMode)ui.equipmentStringMode->currentIndex();
filterData.logged = ui.logged->isChecked();
filterData.planned = ui.planned->isChecked();
diff --git a/desktop-widgets/filterwidget2.ui b/desktop-widgets/filterwidget2.ui
index 44b0dfcfd..c38e651b3 100644
--- a/desktop-widgets/filterwidget2.ui
+++ b/desktop-widgets/filterwidget2.ui
@@ -35,20 +35,26 @@
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="filterButtonExplanation">
+ <item row="3" column="2">
+ <widget class="QDoubleSpinBox" name="minWaterTemp"/>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_7">
<property name="text">
- <string>Reset / close</string>
+ <string>Tags</string>
</property>
</widget>
</item>
<item row="8" column="4" colspan="2">
<widget class="QLineEdit" name="tags"/>
</item>
- <item row="1" column="1">
- <widget class="QLabel" name="label_3">
+ <item row="9" column="4" colspan="2">
+ <widget class="QLineEdit" name="people"/>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_10">
<property name="text">
- <string>Min</string>
+ <string>Suit</string>
</property>
</widget>
</item>
@@ -59,32 +65,22 @@
</property>
</widget>
</item>
- <item row="3" column="4">
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>Max</string>
+ <item row="0" column="2">
+ <widget class="QToolButton" name="close">
+ <property name="toolTip">
+ <string>Close filters</string>
</property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Rating</string>
+ <property name="icon">
+ <iconset>
+ <normaloff>:filter-close</normaloff>:filter-close</iconset>
</property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Tags</string>
+ <property name="autoRaise">
+ <bool>true</bool>
</property>
</widget>
</item>
- <item row="3" column="2">
- <widget class="QDoubleSpinBox" name="minWaterTemp"/>
- </item>
- <item row="2" column="4">
- <widget class="QLabel" name="label_16">
+ <item row="1" column="4">
+ <widget class="QLabel" name="label_15">
<property name="text">
<string>Max</string>
</property>
@@ -97,59 +93,95 @@
</property>
</widget>
</item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_4">
+ <item row="7" column="4">
+ <widget class="QCheckBox" name="planned">
<property name="text">
- <string>From</string>
+ <string>Planned</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>To</string>
+ <item row="11" column="4" colspan="2">
+ <widget class="QLineEdit" name="equipment"/>
+ </item>
+ <item row="13" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- </widget>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
</item>
- <item row="4" column="1">
- <widget class="QLabel" name="label_17">
+ <item row="2" column="1">
+ <widget class="QLabel" name="label_14">
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
- <item row="3" column="5">
- <widget class="QDoubleSpinBox" name="maxWaterTemp"/>
+ <item row="10" column="4" colspan="2">
+ <widget class="QLineEdit" name="location"/>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_5">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
<property name="text">
- <string>Visibility</string>
+ <string>Rating</string>
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Min</string>
+ <item row="1" column="5">
+ <widget class="StarWidget" name="maxRating" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
</property>
</widget>
</item>
- <item row="1" column="4">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Max</string>
+ <item row="2" column="5">
+ <widget class="StarWidget" name="maxVisibility" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
</property>
</widget>
</item>
- <item row="10" column="4" colspan="2">
- <widget class="QLineEdit" name="location"/>
- </item>
- <item row="11" column="4" colspan="2">
- <widget class="QLineEdit" name="suit"/>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Min</string>
+ </property>
+ </widget>
</item>
- <item row="12" column="4" colspan="2">
- <widget class="QLineEdit" name="dnotes"/>
+ <item row="0" column="1">
+ <widget class="QToolButton" name="clear">
+ <property name="toolTip">
+ <string>Reset filters</string>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:edit-clear-icon</normaloff>:edit-clear-icon</iconset>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="labelEquipment">
@@ -158,27 +190,15 @@
</property>
</widget>
</item>
- <item row="4" column="2">
- <widget class="QDoubleSpinBox" name="minAirTemp"/>
- </item>
- <item row="4" column="5">
- <widget class="QDoubleSpinBox" name="maxAirTemp"/>
- </item>
- <item row="11" column="4" colspan="2">
- <widget class="QLineEdit" name="equipment"/>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_11">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_5">
<property name="text">
- <string>Water Temp</string>
+ <string>Visibility</string>
</property>
</widget>
</item>
- <item row="9" column="4" colspan="2">
- <widget class="QLineEdit" name="people"/>
- </item>
- <item row="4" column="4">
- <widget class="QLabel" name="label_18">
+ <item row="2" column="4">
+ <widget class="QLabel" name="label_16">
<property name="text">
<string>Max</string>
</property>
@@ -191,10 +211,34 @@
</property>
</widget>
</item>
- <item row="11" column="0">
- <widget class="QLabel" name="label_10">
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_6">
<property name="text">
- <string>Suit</string>
+ <string>To</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="label_17">
+ <property name="text">
+ <string>Min</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="logged">
+ <property name="text">
+ <string>Logged</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="2">
+ <widget class="QDateTimeEdit" name="fromDate">
+ <property name="calendarPopup">
+ <bool>true</bool>
</property>
</widget>
</item>
@@ -205,6 +249,22 @@
</property>
</widget>
</item>
+ <item row="11" column="4" colspan="2">
+ <widget class="QLineEdit" name="suit"/>
+ </item>
+ <item row="4" column="2">
+ <widget class="QDoubleSpinBox" name="minAirTemp"/>
+ </item>
+ <item row="5" column="4">
+ <widget class="QTimeEdit" name="fromTime"/>
+ </item>
+ <item row="3" column="4">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Max</string>
+ </property>
+ </widget>
+ </item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
@@ -212,8 +272,8 @@
</property>
</widget>
</item>
- <item row="2" column="5">
- <widget class="StarWidget" name="maxVisibility" native="true">
+ <item row="2" column="2">
+ <widget class="StarWidget" name="minVisibility" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -225,19 +285,19 @@
</property>
</widget>
</item>
- <item row="2" column="2">
- <widget class="StarWidget" name="minVisibility" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::TabFocus</enum>
+ <item row="4" column="5">
+ <widget class="QDoubleSpinBox" name="maxAirTemp"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Water Temp</string>
</property>
</widget>
</item>
+ <item row="3" column="5">
+ <widget class="QDoubleSpinBox" name="maxWaterTemp"/>
+ </item>
<item row="1" column="2">
<widget class="StarWidget" name="minRating" native="true">
<property name="sizePolicy">
@@ -251,88 +311,41 @@
</property>
</widget>
</item>
- <item row="1" column="5">
- <widget class="StarWidget" name="maxRating" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::TabFocus</enum>
- </property>
- </widget>
+ <item row="12" column="4" colspan="2">
+ <widget class="QLineEdit" name="dnotes"/>
</item>
- <item row="7" column="1">
- <widget class="QCheckBox" name="logged">
- <property name="text">
- <string>Logged</string>
- </property>
- <property name="checked">
+ <item row="6" column="1" colspan="2">
+ <widget class="QDateTimeEdit" name="toDate">
+ <property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
- <item row="7" column="4">
- <widget class="QCheckBox" name="planned">
+ <item row="4" column="4">
+ <widget class="QLabel" name="label_18">
<property name="text">
- <string>Planned</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="5" column="4">
- <widget class="QTimeEdit" name="fromTime"/>
- </item>
- <item row="5" column="1" colspan="2">
- <widget class="QDateTimeEdit" name="fromDate">
- <property name="calendarPopup">
- <bool>true</bool>
+ <string>Max</string>
</property>
</widget>
</item>
- <item row="6" column="1" colspan="2">
- <widget class="QDateTimeEdit" name="toDate">
- <property name="calendarPopup">
- <bool>true</bool>
+ <item row="0" column="0">
+ <widget class="QLabel" name="filterButtonExplanation">
+ <property name="text">
+ <string>Reset / close</string>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QTimeEdit" name="toTime"/>
</item>
- <item row="0" column="2">
- <widget class="QToolButton" name="close">
- <property name="toolTip">
- <string>Close filters</string>
- </property>
- <property name="icon">
- <iconset>
- <normaloff>:filter-close</normaloff>:filter-close</iconset>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QToolButton" name="clear">
- <property name="toolTip">
- <string>Reset filters</string>
- </property>
- <property name="icon">
- <iconset>
- <normaloff>:edit-clear-icon</normaloff>:edit-clear-icon</iconset>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>From</string>
</property>
</widget>
</item>
- <item row="8" column="1" colspan="2">
+ <item row="8" column="1">
<widget class="QComboBox" name="tagsMode">
<item>
<property name="text">
@@ -351,7 +364,26 @@
</item>
</widget>
</item>
- <item row="9" column="1" colspan="2">
+ <item row="8" column="2">
+ <widget class="QComboBox" name="tagsStringMode">
+ <item>
+ <property name="text">
+ <string>Substring</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Starts with</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exact</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="9" column="1">
<widget class="QComboBox" name="peopleMode">
<item>
<property name="text">
@@ -370,7 +402,26 @@
</item>
</widget>
</item>
- <item row="10" column="1" colspan="2">
+ <item row="9" column="2">
+ <widget class="QComboBox" name="peopleStringMode">
+ <item>
+ <property name="text">
+ <string>Substring</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Starts with</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exact</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="10" column="1">
<widget class="QComboBox" name="locationMode">
<item>
<property name="text">
@@ -389,7 +440,26 @@
</item>
</widget>
</item>
- <item row="11" column="1" colspan="2">
+ <item row="10" column="2">
+ <widget class="QComboBox" name="locationStringMode">
+ <item>
+ <property name="text">
+ <string>Substring</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Starts with</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exact</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="11" column="1">
<widget class="QComboBox" name="suitMode">
<item>
<property name="text">
@@ -408,7 +478,7 @@
</item>
</widget>
</item>
- <item row="12" column="1" colspan="2">
+ <item row="12" column="1">
<widget class="QComboBox" name="dnotesMode">
<item>
<property name="text">
@@ -427,7 +497,7 @@
</item>
</widget>
</item>
- <item row="13" column="1" colspan="2">
+ <item row="13" column="1">
<widget class="QComboBox" name="equipmentMode">
<item>
<property name="text">
@@ -446,18 +516,62 @@
</item>
</widget>
</item>
- <item row="13" column="0">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
+ <item row="11" column="2">
+ <widget class="QComboBox" name="suitStringMode">
+ <item>
+ <property name="text">
+ <string>Substring</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Starts with</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exact</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="12" column="2">
+ <widget class="QComboBox" name="dnotesStringMode">
+ <item>
+ <property name="text">
+ <string>Substring</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Starts with</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exact</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="13" column="2">
+ <widget class="QComboBox" name="equipmentStringMode">
+ <item>
+ <property name="text">
+ <string>Substring</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Starts with</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exact</string>
+ </property>
+ </item>
+ </widget>
</item>
</layout>
</widget>