diff options
-rw-r--r-- | src/core/EntrySearcher.cpp | 18 | ||||
-rw-r--r-- | src/core/EntrySearcher.h | 5 | ||||
-rw-r--r-- | src/gui/SearchHelpWidget.ui | 7 | ||||
-rw-r--r-- | tests/TestEntrySearcher.cpp | 57 | ||||
-rw-r--r-- | tests/TestEntrySearcher.h | 1 |
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; |