Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBO41 <botbob@disroot.org>2020-05-08 18:13:15 +0300
committerJonathan White <support@dmapps.us>2020-05-14 23:48:57 +0300
commitf1080d633ed72e032899fa944d07ef210fc3c184 (patch)
tree1ca0704ed27d01d09e27cc89330fcf8fd05be65a
parent485852c9dbc748055e1567f5bdad997905309c7e (diff)
Add group search
* Allow searching by group using the `group:` field. * Group hierarchies can be searched by including a '/' in the search term.
-rw-r--r--src/core/EntrySearcher.cpp18
-rw-r--r--src/core/EntrySearcher.h5
-rw-r--r--src/gui/SearchHelpWidget.ui7
-rw-r--r--tests/TestEntrySearcher.cpp57
-rw-r--r--tests/TestEntrySearcher.h1
5 files changed, 82 insertions, 6 deletions
diff --git a/src/core/EntrySearcher.cpp b/src/core/EntrySearcher.cpp
index 21b86a7a1..eccffe0a5 100644
--- a/src/core/EntrySearcher.cpp
+++ b/src/core/EntrySearcher.cpp
@@ -54,7 +54,6 @@ QList<Entry*> EntrySearcher::search(const QList<SearchTerm>& searchTerms, const
QList<Entry*> EntrySearcher::search(const QString& searchString, const Group* baseGroup, bool forceSearch)
{
Q_ASSERT(baseGroup);
-
parseSearchTerms(searchString);
return repeat(baseGroup, forceSearch);
}
@@ -73,7 +72,7 @@ QList<Entry*> EntrySearcher::repeat(const Group* baseGroup, bool forceSearch)
QList<Entry*> results;
for (const auto group : baseGroup->groupsRecursive(true)) {
if (forceSearch || group->resolveSearchingEnabled()) {
- for (auto* entry : group->entries()) {
+ for (const auto entry : group->entries()) {
if (searchEntryImpl(entry)) {
results.append(entry);
}
@@ -142,12 +141,14 @@ bool EntrySearcher::isCaseSensitive()
return m_caseSensitive;
}
-bool EntrySearcher::searchEntryImpl(Entry* entry)
+bool EntrySearcher::searchEntryImpl(const Entry* entry)
{
// Pre-load in case they are needed
auto attributes_keys = entry->attributes()->customKeys();
auto attributes = QStringList(attributes_keys + entry->attributes()->values(attributes_keys));
auto attachments = QStringList(entry->attachments()->keys());
+ // Build a group hierarchy to allow searching for e.g. /group1/subgroup*
+ auto hierarchy = entry->group()->hierarchy().join('/').prepend("/");
bool found;
for (const auto& term : m_searchTerms) {
@@ -181,6 +182,14 @@ bool EntrySearcher::searchEntryImpl(Entry* entry)
found = entry->attributes()->contains(term.word)
&& term.regex.match(entry->attributes()->value(term.word)).hasMatch();
break;
+ case Field::Group:
+ // Match against the full hierarchy if the word contains a '/' otherwise just the group name
+ if (term.word.contains('/')) {
+ found = term.regex.match(hierarchy).hasMatch();
+ } else {
+ found = term.regex.match(entry->group()->name()).hasMatch();
+ }
+ break;
default:
// Terms without a specific field try to match title, username, url, and notes
found = term.regex.match(entry->resolvePlaceholder(entry->title())).hasMatch()
@@ -209,7 +218,8 @@ void EntrySearcher::parseSearchTerms(const QString& searchString)
{QStringLiteral("title"), Field::Title},
{QStringLiteral("u"), Field::Username}, // u: stands for username rather than url
{QStringLiteral("url"), Field::Url},
- {QStringLiteral("username"), Field::Username}};
+ {QStringLiteral("username"), Field::Username},
+ {QStringLiteral("group"), Field::Group}};
m_searchTerms.clear();
auto results = m_termParser.globalMatch(searchString);
diff --git a/src/core/EntrySearcher.h b/src/core/EntrySearcher.h
index 2300fcf29..48d15fb05 100644
--- a/src/core/EntrySearcher.h
+++ b/src/core/EntrySearcher.h
@@ -38,7 +38,8 @@ public:
Notes,
AttributeKV,
Attachment,
- AttributeValue
+ AttributeValue,
+ Group
};
struct SearchTerm
@@ -64,7 +65,7 @@ public:
bool isCaseSensitive();
private:
- bool searchEntryImpl(Entry* entry);
+ bool searchEntryImpl(const Entry* entry);
void parseSearchTerms(const QString& searchString);
bool m_caseSensitive;
diff --git a/src/gui/SearchHelpWidget.ui b/src/gui/SearchHelpWidget.ui
index d2d8a2339..ebc62e991 100644
--- a/src/gui/SearchHelpWidget.ui
+++ b/src/gui/SearchHelpWidget.ui
@@ -235,6 +235,13 @@
</property>
</widget>
</item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string notr="true">group (g)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/tests/TestEntrySearcher.cpp b/tests/TestEntrySearcher.cpp
index 7107cff0a..3a0ac6836 100644
--- a/tests/TestEntrySearcher.cpp
+++ b/tests/TestEntrySearcher.cpp
@@ -262,3 +262,60 @@ void TestEntrySearcher::testCustomAttributesAreSearched()
m_searchResult = m_entrySearcher.search("_testAttribute:test _testProtected:testP2", m_rootGroup);
QCOMPARE(m_searchResult.count(), 2);
}
+
+void TestEntrySearcher::testGroup()
+{
+ /**
+ * Root
+ * - group1 (1 entry)
+ * - subgroup1 (2 entries)
+ * - group2
+ * - subgroup2 (1 entry)
+ */
+ Group* group1 = new Group();
+ Group* group2 = new Group();
+
+ group1->setParent(m_rootGroup);
+ group1->setName("group1");
+ group2->setParent(m_rootGroup);
+ group2->setName("group2");
+
+ Group* subgroup1 = new Group();
+ subgroup1->setName("subgroup1");
+ subgroup1->setParent(group1);
+
+ Group* subgroup2 = new Group();
+ subgroup2->setName("subgroup2");
+ subgroup2->setParent(group2);
+
+ Entry* eGroup1 = new Entry();
+ eGroup1->setTitle("Entry Group 1");
+ eGroup1->setGroup(group1);
+
+ Entry* eSub1 = new Entry();
+ eSub1->setTitle("test search term test");
+ eSub1->setGroup(subgroup1);
+
+ Entry* eSub2 = new Entry();
+ eSub2->setNotes("test test");
+ eSub2->setGroup(subgroup1);
+
+ Entry* eSub3 = new Entry();
+ eSub3->setNotes("test term test");
+ eSub3->setGroup(subgroup2);
+
+ m_searchResult = m_entrySearcher.search("group:subgroup", m_rootGroup);
+ QCOMPARE(m_searchResult.count(), 3);
+
+ m_searchResult = m_entrySearcher.search("g:subgroup1", m_rootGroup);
+ QCOMPARE(m_searchResult.count(), 2);
+
+ m_searchResult = m_entrySearcher.search("g:subgroup1 search", m_rootGroup);
+ QCOMPARE(m_searchResult.count(), 1);
+
+ m_searchResult = m_entrySearcher.search("g:*1/sub*1", m_rootGroup);
+ QCOMPARE(m_searchResult.count(), 2);
+
+ m_searchResult = m_entrySearcher.search("g:/group1 search", m_rootGroup);
+ QCOMPARE(m_searchResult.count(), 1);
+}
diff --git a/tests/TestEntrySearcher.h b/tests/TestEntrySearcher.h
index fb4312926..498a00742 100644
--- a/tests/TestEntrySearcher.h
+++ b/tests/TestEntrySearcher.h
@@ -36,6 +36,7 @@ private slots:
void testAllAttributesAreSearched();
void testSearchTermParser();
void testCustomAttributesAreSearched();
+ void testGroup();
private:
Group* m_rootGroup;