Streamlined searcher code

* Remove searching of group title and notes
* End search when selecting a new group
* Correct entry searcher tests to align with new code
This commit is contained in:
Jonathan White 2018-03-19 23:16:22 -04:00
parent a5e7da67d8
commit d8d758f0e1
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
7 changed files with 39 additions and 60 deletions

View File

@ -22,47 +22,44 @@
QList<Entry*> EntrySearcher::search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity) QList<Entry*> EntrySearcher::search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
{ {
if (!group->resolveSearchingEnabled()) { QList<Entry*> results;
return QList<Entry*>();
if (group->resolveSearchingEnabled()) {
results.append(searchEntries(searchTerm, group->entries(), caseSensitivity));
} }
return searchEntries(searchTerm, group, caseSensitivity); for (Group* childGroup : group->children()) {
} if (childGroup->resolveSearchingEnabled()) {
results.append(searchEntries(searchTerm, childGroup->entries(), caseSensitivity));
QList<Entry*>
EntrySearcher::searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
{
QList<Entry*> searchResult;
const QList<Entry*>& entryList = group->entries();
for (Entry* entry : entryList) {
searchResult.append(matchEntry(searchTerm, entry, caseSensitivity));
}
const QList<Group*>& children = group->children();
for (Group* childGroup : children) {
if (childGroup->searchingEnabled() != Group::Disable) {
if (matchGroup(searchTerm, childGroup, caseSensitivity)) {
searchResult.append(childGroup->entriesRecursive());
} else {
searchResult.append(searchEntries(searchTerm, childGroup, caseSensitivity));
}
} }
} }
return searchResult; return results;
} }
QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity) QList<Entry*> EntrySearcher::searchEntries(const QString& searchTerm, const QList<Entry*>& entries,
Qt::CaseSensitivity caseSensitivity)
{
QList<Entry*> results;
for (Entry* entry : entries) {
if (matchEntry(searchTerm, entry, caseSensitivity)) {
results.append(entry);
}
}
return results;
}
bool EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry,
Qt::CaseSensitivity caseSensitivity)
{ {
const QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts); const QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
for (const QString& word : wordList) { for (const QString& word : wordList) {
if (!wordMatch(word, entry, caseSensitivity)) { if (!wordMatch(word, entry, caseSensitivity)) {
return QList<Entry*>(); return false;
} }
} }
return QList<Entry*>() << entry; return true;
} }
bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity) bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity)
@ -72,20 +69,3 @@ bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensiti
|| entry->resolvePlaceholder(entry->url()).contains(word, caseSensitivity) || entry->resolvePlaceholder(entry->url()).contains(word, caseSensitivity)
|| entry->resolvePlaceholder(entry->notes()).contains(word, caseSensitivity); || entry->resolvePlaceholder(entry->notes()).contains(word, caseSensitivity);
} }
bool EntrySearcher::matchGroup(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
{
const QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
for (const QString& word : wordList) {
if (!wordMatch(word, group, caseSensitivity)) {
return false;
}
}
return true;
}
bool EntrySearcher::wordMatch(const QString& word, const Group* group, Qt::CaseSensitivity caseSensitivity)
{
return group->name().contains(word, caseSensitivity) || group->notes().contains(word, caseSensitivity);
}

View File

@ -30,11 +30,9 @@ public:
QList<Entry*> search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity); QList<Entry*> search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
private: private:
QList<Entry*> searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity); QList<Entry*> searchEntries(const QString& searchTerm, const QList<Entry*>& entries, Qt::CaseSensitivity caseSensitivity);
QList<Entry*> matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity); bool matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity);
bool wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity); bool wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity);
bool matchGroup(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
bool wordMatch(const QString& word, const Group* group, Qt::CaseSensitivity caseSensitivity);
}; };
#endif // KEEPASSX_ENTRYSEARCHER_H #endif // KEEPASSX_ENTRYSEARCHER_H

View File

@ -1047,9 +1047,12 @@ void DatabaseWidget::setSearchLimitGroup(bool state)
void DatabaseWidget::onGroupChanged(Group* group) void DatabaseWidget::onGroupChanged(Group* group)
{ {
// Intercept group changes if in search mode if (isInSearchMode() && m_searchLimitGroup) {
if (isInSearchMode()) { // Perform new search if we are limiting search to the current group
search(m_lastSearchText); search(m_lastSearchText);
} else if (isInSearchMode()) {
// Otherwise cancel search
emit clearSearch();
} else { } else {
m_entryView->setGroup(group); m_entryView->setGroup(group);
} }

View File

@ -138,7 +138,7 @@ signals:
void mainSplitterSizesChanged(); void mainSplitterSizesChanged();
void previewSplitterSizesChanged(); void previewSplitterSizesChanged();
void entryViewStateChanged(); void entryViewStateChanged();
void updateSearch(QString text); void clearSearch();
public slots: public slots:
void createEntry(); void createEntry();

View File

@ -113,6 +113,7 @@ void SearchWidget::connectSignals(SignalMultiplexer& mx)
mx.connect(this, SIGNAL(limitGroupChanged(bool)), SLOT(setSearchLimitGroup(bool))); mx.connect(this, SIGNAL(limitGroupChanged(bool)), SLOT(setSearchLimitGroup(bool)));
mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword())); mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword()));
mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus())); mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus()));
mx.connect(SIGNAL(clearSearch()), m_ui->searchEdit, SLOT(clear()));
mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit())); mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit()));
} }

View File

@ -36,14 +36,16 @@ class SearchWidget : public QWidget
public: public:
explicit SearchWidget(QWidget* parent = nullptr); explicit SearchWidget(QWidget* parent = nullptr);
~SearchWidget(); ~SearchWidget() override;
Q_DISABLE_COPY(SearchWidget)
void connectSignals(SignalMultiplexer& mx); void connectSignals(SignalMultiplexer& mx);
void setCaseSensitive(bool state); void setCaseSensitive(bool state);
void setLimitGroup(bool state); void setLimitGroup(bool state);
protected: protected:
bool eventFilter(QObject* obj, QEvent* event); bool eventFilter(QObject* obj, QEvent* event) override;
signals: signals:
void search(const QString& text); void search(const QString& text);
@ -69,8 +71,6 @@ private:
QTimer* m_searchTimer; QTimer* m_searchTimer;
QAction* m_actionCaseSensitive; QAction* m_actionCaseSensitive;
QAction* m_actionLimitGroup; QAction* m_actionLimitGroup;
Q_DISABLE_COPY(SearchWidget)
}; };
#endif // SEARCHWIDGET_H #endif // SEARCHWIDGET_H

View File

@ -53,7 +53,6 @@ void TestEntrySearcher::testSearch()
group2111->setParent(group211); group2111->setParent(group211);
group1->setSearchingEnabled(Group::Disable); group1->setSearchingEnabled(Group::Disable);
group11->setSearchingEnabled(Group::Enable);
Entry* eRoot = new Entry(); Entry* eRoot = new Entry();
eRoot->setNotes("test search term test"); eRoot->setNotes("test search term test");
@ -88,15 +87,13 @@ void TestEntrySearcher::testSearch()
e3b->setGroup(group3); e3b->setGroup(group3);
m_searchResult = m_entrySearcher.search("search term", m_groupRoot, Qt::CaseInsensitive); m_searchResult = m_entrySearcher.search("search term", m_groupRoot, Qt::CaseInsensitive);
QCOMPARE(m_searchResult.count(), 3); QCOMPARE(m_searchResult.count(), 2);
m_searchResult = m_entrySearcher.search("search term", group211, Qt::CaseInsensitive); m_searchResult = m_entrySearcher.search("search term", group211, Qt::CaseInsensitive);
QCOMPARE(m_searchResult.count(), 1); QCOMPARE(m_searchResult.count(), 1);
// Parent group disabled search
m_searchResult = m_entrySearcher.search("search term", group11, Qt::CaseInsensitive); m_searchResult = m_entrySearcher.search("search term", group11, Qt::CaseInsensitive);
QCOMPARE(m_searchResult.count(), 1);
m_searchResult = m_entrySearcher.search("search term", group1, Qt::CaseInsensitive);
QCOMPARE(m_searchResult.count(), 0); QCOMPARE(m_searchResult.count(), 0);
} }