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:
Eberhard Graether
2014-10-24 11:14:31 +02:00
parent a9c93a9437
commit ce91216e97
6 changed files with 55 additions and 24 deletions
+37 -8
View File
@@ -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())
{
+2
View File
@@ -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;
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -15,8 +15,8 @@ public:
OPERATOR_NONE,
OPERATOR_NOT,
OPERATOR_SUB,
OPERATOR_HAS,
OPERATOR_SUB,
OPERATOR_AND,
OPERATOR_OR,
+3 -3
View File
@@ -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"
+10 -10
View File
@@ -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"
);
}