ui: fixed issues in smart search box
* spaces can be entered again * fixed completer disappearing when going through the list * changed query operators to sub: > and has: . and changed
This commit is contained in:
@@ -36,6 +36,7 @@ void QtSmartSearchBox::search()
|
||||
|
||||
QtSmartSearchBox::QtSmartSearchBox(QWidget* parent)
|
||||
: QLineEdit(parent)
|
||||
, m_allowTextChange(false)
|
||||
, m_cursorIndex(0)
|
||||
, m_shiftKeyDown(false)
|
||||
, m_mousePressed(false)
|
||||
@@ -55,6 +56,12 @@ void QtSmartSearchBox::setAutocompletionList(const std::vector<SearchIndex::Sear
|
||||
{
|
||||
m_matches = autocompletionList;
|
||||
|
||||
if (!m_matches.size())
|
||||
{
|
||||
setCompleter(0);
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList wordList;
|
||||
for (const SearchIndex::SearchMatch& match: autocompletionList)
|
||||
{
|
||||
@@ -70,6 +77,8 @@ void QtSmartSearchBox::setAutocompletionList(const std::vector<SearchIndex::Sear
|
||||
|
||||
connect(completer, SIGNAL(highlighted(const QModelIndex&)), this, SLOT(onSearchCompletionHighlighted(const QModelIndex&)), Qt::DirectConnection);
|
||||
connect(completer, SIGNAL(activated(const QModelIndex&)), this, SLOT(onSearchCompletionActivated(const QModelIndex&)), Qt::DirectConnection);
|
||||
|
||||
completer->popup()->setCurrentIndex(completer->completionModel()->index(0, 0));
|
||||
}
|
||||
|
||||
void QtSmartSearchBox::setQuery(const std::string& text)
|
||||
@@ -223,7 +232,7 @@ void QtSmartSearchBox::keyPressEvent(QKeyEvent* event)
|
||||
}
|
||||
else if (event->matches(QKeySequence::Paste))
|
||||
{
|
||||
setText(text() + QApplication::clipboard()->text());
|
||||
setEditText(text() + QApplication::clipboard()->text());
|
||||
onTextEdited(text());
|
||||
return;
|
||||
}
|
||||
@@ -304,8 +313,11 @@ void QtSmartSearchBox::mouseReleaseEvent(QMouseEvent* event)
|
||||
|
||||
void QtSmartSearchBox::onTextEdited(const QString& text)
|
||||
{
|
||||
m_allowTextChange = true;
|
||||
deleteSelectedElements();
|
||||
|
||||
bool tokensChanged = false;
|
||||
|
||||
std::string token;
|
||||
std::deque<std::string> tokens = QueryTree::tokenizeQuery(text.toStdString());
|
||||
while (tokens.size())
|
||||
@@ -317,12 +329,13 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
|
||||
{
|
||||
textToToken(token);
|
||||
token.clear();
|
||||
tokensChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (text.toStdString() != token)
|
||||
if (tokensChanged)
|
||||
{
|
||||
setText(QString::fromStdString(token));
|
||||
setEditText(QString::fromStdString(token));
|
||||
updateElements();
|
||||
}
|
||||
else
|
||||
@@ -338,18 +351,28 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
|
||||
|
||||
void QtSmartSearchBox::onTextChanged(const QString& text)
|
||||
{
|
||||
if (m_oldText.size())
|
||||
if (!m_allowTextChange)
|
||||
{
|
||||
setText(m_oldText);
|
||||
|
||||
// This prevents the completer from disappearing while navigating the completion popup.
|
||||
if (completer() && !completer()->signalsBlocked())
|
||||
{
|
||||
completer()->popup()->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oldText = text;
|
||||
}
|
||||
|
||||
m_oldText.clear();
|
||||
m_allowTextChange = false;
|
||||
|
||||
updatePlaceholder();
|
||||
}
|
||||
|
||||
void QtSmartSearchBox::onSearchCompletionHighlighted(const QModelIndex& index)
|
||||
{
|
||||
m_oldText = text();
|
||||
}
|
||||
|
||||
void QtSmartSearchBox::onSearchCompletionActivated(const QModelIndex& index)
|
||||
@@ -443,6 +466,12 @@ void QtSmartSearchBox::textToToken(std::string text)
|
||||
m_cursorIndex++;
|
||||
}
|
||||
|
||||
void QtSmartSearchBox::setEditText(const QString& text)
|
||||
{
|
||||
m_allowTextChange = true;
|
||||
setText(text);
|
||||
}
|
||||
|
||||
bool QtSmartSearchBox::editTextToElement()
|
||||
{
|
||||
if (text().size())
|
||||
@@ -471,7 +500,7 @@ void QtSmartSearchBox::editElement(QtQueryElement* element)
|
||||
std::string token = QueryTree::getTokenName(m_tokens[m_cursorIndex]);
|
||||
m_tokens.erase(m_tokens.begin() + m_cursorIndex);
|
||||
|
||||
setText(QString::fromStdString(token));
|
||||
setEditText(QString::fromStdString(token));
|
||||
updateElements();
|
||||
|
||||
MessageSearchAutocomplete(token).dispatch();
|
||||
@@ -631,7 +660,7 @@ void QtSmartSearchBox::updatePlaceholder()
|
||||
|
||||
void QtSmartSearchBox::clearLineEdit()
|
||||
{
|
||||
setText("");
|
||||
setEditText("");
|
||||
|
||||
if (completer())
|
||||
{
|
||||
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
void moveCursorTo(int goal);
|
||||
|
||||
void textToToken(std::string text);
|
||||
void setEditText(const QString& text);
|
||||
bool editTextToElement();
|
||||
void editElement(QtQueryElement* element);
|
||||
|
||||
@@ -80,6 +81,7 @@ private:
|
||||
void updatePlaceholder();
|
||||
void clearLineEdit();
|
||||
|
||||
bool m_allowTextChange;
|
||||
QString m_oldText;
|
||||
|
||||
std::deque<std::string> m_tokens;
|
||||
|
||||
@@ -15,8 +15,8 @@ const std::map<char, QueryOperator::OperatorType>& QueryOperator::getOperatorTyp
|
||||
operatorMap.emplace(' ', OPERATOR_NONE);
|
||||
|
||||
operatorMap.emplace('!', OPERATOR_NOT);
|
||||
operatorMap.emplace('.', OPERATOR_SUB);
|
||||
operatorMap.emplace('>', OPERATOR_HAS);
|
||||
operatorMap.emplace('.', OPERATOR_HAS);
|
||||
operatorMap.emplace('>', OPERATOR_SUB);
|
||||
operatorMap.emplace('&', OPERATOR_AND);
|
||||
operatorMap.emplace('|', OPERATOR_OR);
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ public:
|
||||
OPERATOR_NONE,
|
||||
|
||||
OPERATOR_NOT,
|
||||
OPERATOR_SUB,
|
||||
OPERATOR_HAS,
|
||||
OPERATOR_SUB,
|
||||
OPERATOR_AND,
|
||||
OPERATOR_OR,
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
void test_operator_sub()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("'class'.'base'"),
|
||||
printedFilteredTestGraph("'class'>'base'"),
|
||||
|
||||
"1 nodes: class:A\n"
|
||||
"0 edges:\n"
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
void test_operator_has()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("\"A\">'field'"),
|
||||
printedFilteredTestGraph("\"A\".'field'"),
|
||||
|
||||
"1 nodes: field:A::count\n"
|
||||
"0 edges:\n"
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
void test_operator_group()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedFilteredTestGraph("('static'|'const').'public'"),
|
||||
printedFilteredTestGraph("('static'|'const')>'public'"),
|
||||
|
||||
"1 nodes: method:A::getCount\n"
|
||||
"0 edges:\n"
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
|
||||
"A \" INVALID\n"
|
||||
" \"A\"\n"
|
||||
". IMPLICIT\n"
|
||||
"> IMPLICIT\n"
|
||||
" \"\"\n"
|
||||
);
|
||||
}
|
||||
@@ -276,36 +276,36 @@ public:
|
||||
|
||||
"\"A\" ( \"B\" )\n"
|
||||
" \"A\"\n"
|
||||
". IMPLICIT\n"
|
||||
"> IMPLICIT\n"
|
||||
" (\"B\")\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_precedence_not_before_sub()
|
||||
void test_operator_precedence_not_before_has()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedQueryTree("!'method'.!'const'"),
|
||||
printedQueryTree("!'struct'.!'const'"),
|
||||
|
||||
"! 'method' . ! 'const'\n"
|
||||
"! 'struct' . ! 'const'\n"
|
||||
" !\n"
|
||||
" 'method'\n"
|
||||
" 'struct'\n"
|
||||
".\n"
|
||||
" !\n"
|
||||
" 'const'\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_operator_precedence_sub_before_has()
|
||||
void test_operator_precedence_has_before_sub()
|
||||
{
|
||||
TS_ASSERT_EQUALS(
|
||||
printedQueryTree("'namespace'.'class'>'method'"),
|
||||
printedQueryTree("'namespace'.'class'>'base'"),
|
||||
|
||||
"'namespace' . 'class' > 'method'\n"
|
||||
"'namespace' . 'class' > 'base'\n"
|
||||
" 'namespace'\n"
|
||||
" .\n"
|
||||
" 'class'\n"
|
||||
">\n"
|
||||
" 'method'\n"
|
||||
" 'base'\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user