ui: added smart search box
This change switches the search box in the search view from QLineEdit to the derived QtSmartSearchBox implementation, which is capeable of displaying tokens of the query as selectable button elements in different colors. It allows for all the usual mouse and keyboard interactions that the QLineEdit offers. fortune cookie message = Good news from someone dear is coming soon.
This commit is contained in:
@@ -48,10 +48,12 @@ std::map<std::string, QueryCommand::CommandType> QueryCommand::getCommandTypeMap
|
||||
return commandMap;
|
||||
}
|
||||
|
||||
QueryCommand::QueryCommand(const std::string& name)
|
||||
QueryCommand::QueryCommand(std::string name)
|
||||
: m_type(COMMAND_INVALID)
|
||||
, m_name(name)
|
||||
{
|
||||
name.erase(std::remove(name.begin(), name.end(), BOUNDARY), name.end());
|
||||
m_name = name;
|
||||
|
||||
std::map<std::string, CommandType> commandMap = getCommandTypeMap();
|
||||
std::map<std::string, CommandType>::iterator it = commandMap.find(name);
|
||||
|
||||
@@ -85,12 +87,19 @@ bool QueryCommand::derivedIsComplete() const
|
||||
return m_type != COMMAND_INVALID;
|
||||
}
|
||||
|
||||
std::string QueryCommand::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void QueryCommand::print(std::ostream& ostream) const
|
||||
{
|
||||
ostream << m_name;
|
||||
ostream << BOUNDARY << m_name << BOUNDARY;
|
||||
}
|
||||
|
||||
QueryCommand::CommandType QueryCommand::getType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
const char QueryCommand::BOUNDARY = '\'';
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define QUERY_COMMAND_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "data/query/QueryNode.h"
|
||||
|
||||
@@ -46,7 +45,7 @@ public:
|
||||
|
||||
static std::map<std::string, CommandType> getCommandTypeMap();
|
||||
|
||||
QueryCommand(const std::string& name);
|
||||
QueryCommand(std::string name);
|
||||
~QueryCommand();
|
||||
|
||||
virtual bool isCommand() const;
|
||||
@@ -55,13 +54,17 @@ public:
|
||||
|
||||
virtual bool derivedIsComplete() const;
|
||||
|
||||
virtual std::string getName() const;
|
||||
|
||||
virtual void print(std::ostream& ostream) const;
|
||||
|
||||
CommandType getType() const;
|
||||
|
||||
static const char BOUNDARY;
|
||||
|
||||
private:
|
||||
CommandType m_type;
|
||||
const std::string m_name;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
#endif // QUERY_COMMAND_H
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define QUERY_NODE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
class QueryNode
|
||||
{
|
||||
@@ -15,6 +16,8 @@ public:
|
||||
|
||||
virtual bool derivedIsComplete() const = 0;
|
||||
|
||||
virtual std::string getName() const = 0;
|
||||
|
||||
virtual void print(std::ostream& ostream) const = 0;
|
||||
virtual void print(std::ostream& ostream, int n) const;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "data/query/QueryOperator.h"
|
||||
|
||||
#include "data/query/QueryCommand.h"
|
||||
#include "data/query/QueryToken.h"
|
||||
|
||||
const std::map<char, QueryOperator::OperatorType>& QueryOperator::getOperatorTypeMap()
|
||||
@@ -15,11 +16,12 @@ const std::map<char, QueryOperator::OperatorType>& QueryOperator::getOperatorTyp
|
||||
|
||||
operatorMap.emplace('!', OPERATOR_NOT);
|
||||
operatorMap.emplace('.', OPERATOR_SUB);
|
||||
operatorMap.emplace(':', OPERATOR_HAS);
|
||||
operatorMap.emplace('>', OPERATOR_HAS);
|
||||
operatorMap.emplace('&', OPERATOR_AND);
|
||||
operatorMap.emplace('|', OPERATOR_OR);
|
||||
|
||||
operatorMap.emplace(QueryToken::BOUNDARY, OPERATOR_TOKEN);
|
||||
operatorMap.emplace(QueryCommand::BOUNDARY, OPERATOR_COMMAND);
|
||||
|
||||
operatorMap.emplace('(', OPERATOR_GROUP_OPEN);
|
||||
operatorMap.emplace(')', OPERATOR_GROUP_CLOSE);
|
||||
@@ -53,8 +55,9 @@ char QueryOperator::getOperator(OperatorType t)
|
||||
return '\0';
|
||||
}
|
||||
|
||||
QueryOperator::QueryOperator(OperatorType type)
|
||||
QueryOperator::QueryOperator(OperatorType type, bool isImplicit)
|
||||
: m_type(type)
|
||||
, m_isImplicit(isImplicit)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -87,9 +90,19 @@ bool QueryOperator::derivedIsComplete() const
|
||||
return getLeft() && getRight();
|
||||
}
|
||||
|
||||
std::string QueryOperator::getName() const
|
||||
{
|
||||
return std::string(1, getOperator(m_type));
|
||||
}
|
||||
|
||||
void QueryOperator::print(std::ostream& ostream) const
|
||||
{
|
||||
ostream << getOperator(m_type);
|
||||
|
||||
if (isImplicit())
|
||||
{
|
||||
ostream << " IMPLICIT";
|
||||
}
|
||||
}
|
||||
|
||||
void QueryOperator::print(std::ostream& ostream, int n) const
|
||||
@@ -136,3 +149,8 @@ bool QueryOperator::lowerPrecedence(const QueryOperator& other)
|
||||
{
|
||||
return m_type < other.m_type;
|
||||
}
|
||||
|
||||
bool QueryOperator::isImplicit() const
|
||||
{
|
||||
return m_isImplicit;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ public:
|
||||
OPERATOR_OR,
|
||||
|
||||
OPERATOR_TOKEN,
|
||||
OPERATOR_COMMAND,
|
||||
|
||||
OPERATOR_GROUP_OPEN,
|
||||
OPERATOR_GROUP_CLOSE
|
||||
};
|
||||
@@ -29,7 +31,7 @@ public:
|
||||
static OperatorType getOperatorType(char c);
|
||||
static char getOperator(OperatorType t);
|
||||
|
||||
QueryOperator(OperatorType type);
|
||||
QueryOperator(OperatorType type, bool isImplicit);
|
||||
~QueryOperator();
|
||||
|
||||
virtual bool isCommand() const;
|
||||
@@ -38,6 +40,8 @@ public:
|
||||
|
||||
virtual bool derivedIsComplete() const;
|
||||
|
||||
virtual std::string getName() const;
|
||||
|
||||
virtual void print(std::ostream& ostream) const;
|
||||
virtual void print(std::ostream& ostream, int n) const;
|
||||
|
||||
@@ -51,11 +55,14 @@ public:
|
||||
|
||||
bool lowerPrecedence(const QueryOperator& other);
|
||||
|
||||
bool isImplicit() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<QueryNode> m_left;
|
||||
std::shared_ptr<QueryNode> m_right;
|
||||
|
||||
const OperatorType m_type;
|
||||
bool m_isImplicit;
|
||||
};
|
||||
|
||||
#endif // QUERY_OPERATOR_H
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
QueryToken::QueryToken(const std::string& name)
|
||||
QueryToken::QueryToken(std::string name)
|
||||
{
|
||||
name.erase(std::remove(name.begin(), name.end(), BOUNDARY), name.end());
|
||||
std::deque<std::string> names = utility::split(name, DELIMITER);
|
||||
|
||||
m_tokenName = names.front();
|
||||
@@ -50,6 +51,11 @@ bool QueryToken::derivedIsComplete() const
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string QueryToken::getName() const
|
||||
{
|
||||
return m_tokenName;
|
||||
}
|
||||
|
||||
void QueryToken::print(std::ostream& ostream) const
|
||||
{
|
||||
ostream << BOUNDARY << m_tokenName;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define QUERY_TOKEN_H
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "data/query/QueryNode.h"
|
||||
#include "utility/types.h"
|
||||
@@ -11,7 +10,7 @@ class QueryToken
|
||||
: public QueryNode
|
||||
{
|
||||
public:
|
||||
QueryToken(const std::string& name);
|
||||
QueryToken(std::string name);
|
||||
~QueryToken();
|
||||
|
||||
virtual bool isCommand() const;
|
||||
@@ -20,6 +19,8 @@ public:
|
||||
|
||||
virtual bool derivedIsComplete() const;
|
||||
|
||||
virtual std::string getName() const;
|
||||
|
||||
virtual void print(std::ostream& ostream) const;
|
||||
|
||||
const std::string& getTokenName() const;
|
||||
|
||||
@@ -16,7 +16,10 @@ std::deque<std::string> QueryTree::tokenizeQuery(const std::string& query)
|
||||
}
|
||||
|
||||
char operatorToken = QueryOperator::getOperator(QueryOperator::OPERATOR_TOKEN);
|
||||
char operatorCommand = QueryOperator::getOperator(QueryOperator::OPERATOR_COMMAND);
|
||||
|
||||
bool isToken = false;
|
||||
bool isCommand = false;
|
||||
|
||||
std::string token;
|
||||
std::deque<std::string> tokens;
|
||||
@@ -28,12 +31,19 @@ std::deque<std::string> QueryTree::tokenizeQuery(const std::string& query)
|
||||
|
||||
token += tokenTmp;
|
||||
|
||||
if (tokenTmp.size() == 1 && tokenTmp[0] == operatorToken)
|
||||
if (tokenTmp.size() == 1)
|
||||
{
|
||||
isToken = !isToken;
|
||||
if (tokenTmp[0] == operatorToken && !isCommand)
|
||||
{
|
||||
isToken = !isToken;
|
||||
}
|
||||
else if (tokenTmp[0] == operatorCommand && !isToken)
|
||||
{
|
||||
isCommand = !isCommand;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isToken || (!tokensTmp.size() && token.size()))
|
||||
if ((!isToken && !isCommand) || (!tokensTmp.size() && token.size()))
|
||||
{
|
||||
tokens.push_back(token);
|
||||
token.clear();
|
||||
@@ -43,14 +53,47 @@ std::deque<std::string> QueryTree::tokenizeQuery(const std::string& query)
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::string QueryTree::getTokenName(const std::string& token)
|
||||
{
|
||||
if (token.size() > 2 && token.front() == QueryToken::BOUNDARY && token.back() == QueryToken::BOUNDARY)
|
||||
{
|
||||
return QueryToken(token).getName();
|
||||
}
|
||||
else if (token.size() > 2 && token.front() == QueryCommand::BOUNDARY && token.back() == QueryCommand::BOUNDARY)
|
||||
{
|
||||
return QueryCommand(token).getName();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
std::string QueryTree::getTokenTypeName(const std::string& token)
|
||||
{
|
||||
if (token.size() > 2 && token.front() == QueryToken::BOUNDARY && token.back() == QueryToken::BOUNDARY)
|
||||
{
|
||||
return "token";
|
||||
}
|
||||
else if (token.size() > 2 && token.front() == QueryCommand::BOUNDARY && token.back() == QueryCommand::BOUNDARY)
|
||||
{
|
||||
return "command";
|
||||
}
|
||||
else if (token.size() == 1 && QueryOperator::getOperatorType(token.front()) != QueryOperator::OPERATOR_NONE)
|
||||
{
|
||||
return "operator";
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
QueryTree::QueryTree()
|
||||
: m_valid(true)
|
||||
{
|
||||
}
|
||||
|
||||
QueryTree::QueryTree(const std::string& query)
|
||||
: m_valid(true)
|
||||
{
|
||||
std::deque<std::string> tokens = tokenizeQuery(query);
|
||||
|
||||
m_query = utility::join(tokens, ' ');
|
||||
|
||||
m_root = buildTree(tokens, nullptr);
|
||||
build(query);
|
||||
}
|
||||
|
||||
QueryTree::~QueryTree()
|
||||
@@ -67,6 +110,16 @@ bool QueryTree::isValid() const
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
void QueryTree::build(const std::string& query)
|
||||
{
|
||||
std::deque<std::string> tokens = tokenizeQuery(query);
|
||||
|
||||
m_query = utility::join(tokens, ' ');
|
||||
|
||||
m_valid = true;
|
||||
m_root = buildTree(tokens, nullptr);
|
||||
}
|
||||
|
||||
void QueryTree::print(std::ostream& ostream) const
|
||||
{
|
||||
ostream << m_query;
|
||||
@@ -99,7 +152,7 @@ std::shared_ptr<QueryNode> QueryTree::buildTree(std::deque<std::string>& tokens,
|
||||
{
|
||||
if (node->isComplete())
|
||||
{
|
||||
std::shared_ptr<QueryOperator> subNode = std::make_shared<QueryOperator>(QueryOperator::OPERATOR_SUB);
|
||||
std::shared_ptr<QueryOperator> subNode = std::make_shared<QueryOperator>(QueryOperator::OPERATOR_SUB, true);
|
||||
subNode->setLeft(frontNode);
|
||||
subNode->setRight(node);
|
||||
node = subNode;
|
||||
@@ -207,11 +260,14 @@ std::shared_ptr<QueryNode> QueryTree::getNextNode(std::deque<std::string>& token
|
||||
case QueryOperator::OPERATOR_HAS:
|
||||
case QueryOperator::OPERATOR_AND:
|
||||
case QueryOperator::OPERATOR_OR:
|
||||
return std::make_shared<QueryOperator>(type);
|
||||
return std::make_shared<QueryOperator>(type, false);
|
||||
|
||||
case QueryOperator::OPERATOR_TOKEN:
|
||||
return createToken(token);
|
||||
|
||||
case QueryOperator::OPERATOR_COMMAND:
|
||||
return createCommand(token);
|
||||
|
||||
case QueryOperator::OPERATOR_GROUP_OPEN:
|
||||
return buildGroup(tokens, QueryOperator::OPERATOR_GROUP_CLOSE);
|
||||
case QueryOperator::OPERATOR_GROUP_CLOSE:
|
||||
@@ -219,7 +275,7 @@ std::shared_ptr<QueryNode> QueryTree::getNextNode(std::deque<std::string>& token
|
||||
break;
|
||||
|
||||
case QueryOperator::OPERATOR_NONE:
|
||||
return createCommand(token);
|
||||
return createToken(token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,12 +284,16 @@ std::shared_ptr<QueryNode> QueryTree::getNextNode(std::deque<std::string>& token
|
||||
|
||||
std::shared_ptr<QueryNode> QueryTree::createCommand(const std::string& name)
|
||||
{
|
||||
if (name.size() < 3 || name.front() != QueryCommand::BOUNDARY || name.back() != QueryCommand::BOUNDARY)
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
|
||||
std::shared_ptr<QueryCommand> node = std::make_shared<QueryCommand>(name);
|
||||
|
||||
if (node->getType() == QueryCommand::COMMAND_INVALID)
|
||||
{
|
||||
m_valid = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -244,10 +304,9 @@ std::shared_ptr<QueryNode> QueryTree::createToken(const std::string& name)
|
||||
if (name.size() < 3 || name.front() != QueryToken::BOUNDARY || name.back() != QueryToken::BOUNDARY)
|
||||
{
|
||||
m_valid = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<QueryToken>(name.substr(1, name.size() - 2));
|
||||
return std::make_shared<QueryToken>(name);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const QueryTree& tree)
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
#include "data/query/QueryOperator.h"
|
||||
|
||||
class QueryNode;
|
||||
|
||||
class QueryTree
|
||||
{
|
||||
public:
|
||||
static std::deque<std::string> tokenizeQuery(const std::string& query);
|
||||
static std::string getTokenName(const std::string& token);
|
||||
static std::string getTokenTypeName(const std::string& token);
|
||||
|
||||
QueryTree();
|
||||
QueryTree(const std::string& query);
|
||||
~QueryTree();
|
||||
|
||||
@@ -22,6 +23,8 @@ public:
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void build(const std::string& query);
|
||||
|
||||
void print(std::ostream& ostream) const;
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user