Skip to content

Commit f6d24da

Browse files
committed
Cleanup code and search widget display
* Make search widget larger * Move regex converter into Tools namespace * Use QSharedPointer for search terms
1 parent b8f172c commit f6d24da

File tree

6 files changed

+67
-40
lines changed

6 files changed

+67
-40
lines changed

src/core/EntrySearcher.cpp

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
#include "EntrySearcher.h"
2020

2121
#include "core/Group.h"
22+
#include "core/Tools.h"
2223

23-
EntrySearcher::EntrySearcher(bool caseSensitive) :
24-
m_caseSensitive(caseSensitive)
24+
EntrySearcher::EntrySearcher(bool caseSensitive)
25+
: m_caseSensitive(caseSensitive)
26+
, m_termParser(R"re(([-*+]+)?(?:(\w*):)?(?:(?=")"((?:[^"\\]|\\.)*)"|([^ ]*))( |$))re")
27+
// Group 1 = modifiers, Group 2 = field, Group 3 = quoted string, Group 4 = unquoted string
2528
{
2629
}
2730

@@ -60,14 +63,14 @@ void EntrySearcher::setCaseSensitive(bool state)
6063

6164
bool EntrySearcher::searchEntryImpl(const QString& searchString, Entry* entry)
6265
{
63-
auto searchTerms = parseSearchTerms(searchString);
64-
bool found;
65-
6666
// Pre-load in case they are needed
6767
auto attributes = QStringList(entry->attributes()->keys());
6868
auto attachments = QStringList(entry->attachments()->keys());
6969

70-
for (SearchTerm* term : searchTerms) {
70+
bool found;
71+
auto searchTerms = parseSearchTerms(searchString);
72+
73+
for (const auto& term : searchTerms) {
7174
switch (term->field) {
7275
case Field::Title:
7376
found = term->regex.match(entry->resolvePlaceholder(entry->title())).hasMatch();
@@ -106,18 +109,14 @@ bool EntrySearcher::searchEntryImpl(const QString& searchString, Entry* entry)
106109
return true;
107110
}
108111

109-
QList<EntrySearcher::SearchTerm*> EntrySearcher::parseSearchTerms(const QString& searchString)
112+
QList<QSharedPointer<EntrySearcher::SearchTerm> > EntrySearcher::parseSearchTerms(const QString& searchString)
110113
{
111-
auto terms = QList<SearchTerm*>();
112-
// Group 1 = modifiers, Group 2 = field, Group 3 = quoted string, Group 4 = unquoted string
113-
auto termParser = QRegularExpression(R"re(([-*+]+)?(?:(\w*):)?(?:(?=")"((?:[^"\\]|\\.)*)"|([^ ]*))( |$))re");
114-
// Escape common regex symbols except for *, ?, and |
115-
auto regexEscape = QRegularExpression(R"re(([-[\]{}()+.,\\\/^$#]))re");
114+
auto terms = QList<QSharedPointer<SearchTerm> >();
116115

117-
auto results = termParser.globalMatch(searchString);
116+
auto results = m_termParser.globalMatch(searchString);
118117
while (results.hasNext()) {
119118
auto result = results.next();
120-
auto term = new SearchTerm();
119+
QSharedPointer<SearchTerm> term(new SearchTerm());
121120

122121
// Quoted string group
123122
term->word = result.captured(3);
@@ -129,32 +128,16 @@ QList<EntrySearcher::SearchTerm*> EntrySearcher::parseSearchTerms(const QString&
129128

130129
// If still empty, ignore this match
131130
if (term->word.isEmpty()) {
132-
delete term;
133131
continue;
134132
}
135133

136-
QString regex = term->word;
137-
138-
// Wildcard support (*, ?, |)
139-
if (!result.captured(1).contains("*")) {
140-
regex.replace(regexEscape, "\\\\1");
141-
regex.replace("**", "*");
142-
regex.replace("*", ".*");
143-
regex.replace("?", ".");
144-
}
145-
146-
term->regex = QRegularExpression(regex);
147-
if (!m_caseSensitive) {
148-
term->regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
149-
}
134+
auto mods = result.captured(1);
150135

151-
// Exact modifier
152-
if (result.captured(1).contains("+")) {
153-
term->regex.setPattern("^" + term->regex.pattern() + "$");
154-
}
136+
// Convert term to regex
137+
term->regex = Tools::convertToRegex(term->word, !mods.contains("*"), mods.contains("+"), m_caseSensitive);
155138

156139
// Exclude modifier
157-
term->exclude = result.captured(1).contains("-");
140+
term->exclude = mods.contains("-");
158141

159142
// Determine the field to search
160143
QString field = result.captured(2);

src/core/EntrySearcher.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Entry;
2828
class EntrySearcher
2929
{
3030
public:
31-
EntrySearcher(bool caseSensitive = false);
31+
explicit EntrySearcher(bool caseSensitive = false);
3232

3333
QList<Entry*> search(const QString& searchString, const Group* group);
3434
QList<Entry*> searchEntries(const QString& searchString, const QList<Entry*>& entries);
@@ -57,9 +57,10 @@ class EntrySearcher
5757
bool exclude;
5858
};
5959

60-
QList<SearchTerm*> parseSearchTerms(const QString& searchString);
60+
QList<QSharedPointer<SearchTerm> > parseSearchTerms(const QString& searchString);
6161

6262
bool m_caseSensitive;
63+
QRegularExpression m_termParser;
6364

6465
friend class TestEntrySearcher;
6566
};

src/core/Tools.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <QIODevice>
2525
#include <QLocale>
2626
#include <QStringList>
27+
#include <QRegularExpression>
2728

2829
#include <QElapsedTimer>
2930

@@ -357,4 +358,32 @@ bool createWindowsDACL()
357358
return bSuccess;
358359
}
359360

361+
// Escape common regex symbols except for *, ?, and |
362+
auto regexEscape = QRegularExpression(R"re(([-[\]{}()+.,\\\/^$#]))re");
363+
364+
QRegularExpression convertToRegex(const QString& string, bool useWildcards, bool exactMatch, bool caseSensitive)
365+
{
366+
QString pattern = string;
367+
368+
// Wildcard support (*, ?, |)
369+
if (useWildcards) {
370+
pattern.replace(regexEscape, "\\\\1");
371+
pattern.replace("**", "*");
372+
pattern.replace("*", ".*");
373+
pattern.replace("?", ".");
374+
}
375+
376+
// Exact modifier
377+
if (exactMatch) {
378+
pattern = "^" + pattern + "$";
379+
}
380+
381+
auto regex = QRegularExpression(pattern);
382+
if (!caseSensitive) {
383+
regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
384+
}
385+
386+
return regex;
387+
}
388+
360389
} // namespace Tools

src/core/Tools.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <algorithm>
2929

3030
class QIODevice;
31+
class QRegularExpression;
3132

3233
namespace Tools {
3334

@@ -43,6 +44,8 @@ void wait(int ms);
4344
void disableCoreDumps();
4445
void setupSearchPaths();
4546
bool createWindowsDACL();
47+
QRegularExpression convertToRegex(const QString& string, bool useWildcards = false, bool exactMatch = false,
48+
bool caseSensitive = false);
4649

4750
template <typename RandomAccessIterator, typename T>
4851
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)

src/gui/SearchWidget.ui

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
<property name="orientation">
3535
<enum>Qt::Horizontal</enum>
3636
</property>
37+
<property name="sizeType">
38+
<enum>QSizePolicy::Minimum</enum>
39+
</property>
3740
<property name="sizeHint" stdset="0">
3841
<size>
3942
<width>40</width>
@@ -44,6 +47,18 @@
4447
</item>
4548
<item>
4649
<widget class="QLineEdit" name="searchEdit">
50+
<property name="sizePolicy">
51+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
52+
<horstretch>0</horstretch>
53+
<verstretch>0</verstretch>
54+
</sizepolicy>
55+
</property>
56+
<property name="minimumSize">
57+
<size>
58+
<width>0</width>
59+
<height>0</height>
60+
</size>
61+
</property>
4762
<property name="styleSheet">
4863
<string notr="true">padding:3px</string>
4964
</property>

tests/TestEntrySearcher.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ void TestEntrySearcher::testSearchTermParser()
161161
QCOMPARE(terms[4]->field, EntrySearcher::All);
162162
QCOMPARE(terms[4]->word, QString("noquote"));
163163

164-
qDeleteAll(terms);
165-
166164
// Test wildcard and regex search terms
167165
terms = m_entrySearcher.parseSearchTerms("+url:*.google.com *user:\\d+\\w{2}");
168166

@@ -173,6 +171,4 @@ void TestEntrySearcher::testSearchTermParser()
173171

174172
QCOMPARE(terms[1]->field, EntrySearcher::Username);
175173
QCOMPARE(terms[1]->regex.pattern(), QString("\\d+\\w{2}"));
176-
177-
qDeleteAll(terms);
178174
}

0 commit comments

Comments
 (0)