ui: fixed autocompletion issues

* click in autocompletions list causes search
* right arrow for autocompletion
* changed query operator has from '>' to '.' and operator sub from '.' to '+'
* fixed autocompletions to fit to query
and
* fixed spectral layouting endless looping on unconnected node
This commit is contained in:
Eberhard Graether
2015-02-06 00:51:02 +01:00
parent 1f6d503b9c
commit af1462f955
16 changed files with 206 additions and 126 deletions
+52 -43
View File
@@ -590,18 +590,17 @@ std::string Storage::getNameForNodeWithId(Id id) const
}
}
std::vector<SearchMatch> Storage::getAutocompletionMatches(
const std::string& query, const std::string& word) const
std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& query, const std::string& word) const
{
SearchResults tokenResults;
bool usedSubquery = false;
bool hasQueryResults = false;
if (query.size())
{
usedSubquery = getSubQuerySearchResults(query, word, &tokenResults);
hasQueryResults = getQuerySearchResults(query, word, &tokenResults);
}
if (!usedSubquery && word.size())
if (!hasQueryResults && word.size())
{
tokenResults = m_tokenIndex.runFuzzySearch(word);
}
@@ -692,28 +691,28 @@ std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>&
Edge* edge = dynamic_cast<Edge*>(token);
graph->addEdgeAndAllChildrenAsPlainCopy(edge);
}
}
for(const std::pair<Id, std::shared_ptr<Node>> nodePair : graph->getNodes())
{
Node* node = m_graph.getNodeById(nodePair.first);
for (const std::pair<Id, std::shared_ptr<Node>> nodePair : graph->getNodes())
{
Node* node = m_graph.getNodeById(nodePair.first);
node->forEachEdge(
[graph](Edge* edge)
{
if(edge->getType() != Edge::EdgeType::EDGE_MEMBER)
node->forEachEdge(
[graph](Edge* edge)
{
Node* from = edge->getFrom();
Node* to = edge->getTo();
if(graph->findNode([from](Node* node){return from->getId() == node->getId();}) != NULL
&& graph->findNode([to](Node* node){return to->getId() == node->getId();}) != NULL)
if (edge->getType() != Edge::EdgeType::EDGE_MEMBER)
{
graph->addEdge(edge);
Node* from = edge->getFrom();
Node* to = edge->getTo();
if (graph->findNode([from](Node* node){ return from->getId() == node->getId(); }) != NULL &&
graph->findNode([to](Node* node){ return to->getId() == node->getId(); }) != NULL)
{
graph->addEdge(edge);
}
}
}
}
);
);
}
}
return graph;
@@ -1050,24 +1049,34 @@ TokenLocation* Storage::addTokenLocation(Token* token, const ParseLocation& loc,
return location;
}
bool Storage::getSubQuerySearchResults(
const std::string& query,
const std::string& word,
SearchResults* results
) const {
bool Storage::getQuerySearchResults(const std::string& query, const std::string& word, SearchResults* results) const
{
std::string q = query;
bool isCommand = false;
if (QueryOperator::getOperatorType(q.back()) == QueryOperator::OPERATOR_SUB)
switch (QueryOperator::getOperatorType(q.back()))
{
case QueryOperator::OPERATOR_AND:
case QueryOperator::OPERATOR_NOT:
q.pop_back();
}
else if (QueryOperator::getOperatorType(q.back()) == QueryOperator::OPERATOR_HAS)
{
q.pop_back();
}
else if (QueryOperator::getOperatorType(q.back()) != QueryOperator::OPERATOR_NONE)
{
return false;
case QueryOperator::OPERATOR_HAS:
q.pop_back();
q.append("'member'");
break;
case QueryOperator::OPERATOR_SUB:
q.pop_back();
break;
case QueryOperator::OPERATOR_COMMAND:
isCommand = true;
case QueryOperator::OPERATOR_NONE:
case QueryOperator::OPERATOR_TOKEN:
case QueryOperator::OPERATOR_GROUP_OPEN:
case QueryOperator::OPERATOR_GROUP_CLOSE:
break;
}
QueryTree tree(q);
@@ -1096,27 +1105,27 @@ bool Storage::getSubQuerySearchResults(
{
if (word.size())
{
if (searchNodes.size() > 1)
{
SearchResults res = node->runFuzzySearchOnSelf(word);
results->insert(res.begin(), res.end());
}
else
if (searchNodes.size() == 1 && !isCommand)
{
SearchResults res = node->runFuzzySearch(word);
results->insert(res.begin(), res.end());
}
else
{
SearchResults res = node->runFuzzySearchOnSelf(word);
results->insert(res.begin(), res.end());
}
}
else if (searchNodes.size() == 1)
else if (searchNodes.size() == 1 && !isCommand)
{
for (const std::shared_ptr<SearchNode>& child : node->getChildren())
{
child->addResultsRecursive(*results, 0, child.get());
child->addResultsRecursive(results, 1, child.get());
}
}
else
{
node->addResultsRecursive(*results, 0, node);
node->addResults(results, 1, node);
}
}
+1 -2
View File
@@ -140,8 +140,7 @@ private:
Edge* addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeUsage& typeUsage);
TokenLocation* addTokenLocation(Token* token, const ParseLocation& location, bool isScope = false);
bool getSubQuerySearchResults(
const std::string& query, const std::string& word, SearchResults* results) const;
bool getQuerySearchResults(const std::string& query, const std::string& word, SearchResults* results) const;
void removeNodeIfUnreferenced(Node* node);
@@ -29,6 +29,11 @@ void GraphFilterConductor::filter(const QueryTree* tree, const FilterableGraph*
void GraphFilterConductor::filterRecursively(const QueryNode* node, const FilterableGraph* in, FilterableGraph* out) const
{
if (!node)
{
return;
}
if (node->isOperator())
{
filterOperatorNode(dynamic_cast<const QueryOperator*>(node), in, out);
+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_HAS);
operatorMap.emplace('.', OPERATOR_SUB);
operatorMap.emplace('.', OPERATOR_HAS);
operatorMap.emplace('+', OPERATOR_SUB);
operatorMap.emplace('&', OPERATOR_AND);
operatorMap.emplace('|', OPERATOR_OR);
+10 -5
View File
@@ -161,7 +161,7 @@ SearchResults SearchNode::runFuzzySearch(const std::string& query) const
FuzzyMap m = n->fuzzyMatchRecursive(query, 0, 0, 0);
for (const std::pair<size_t, const SearchNode*>& p : m)
{
addResultsRecursive(result, p.first, p.second);
addResultsRecursive(&result, p.first, p.second);
}
}
@@ -176,7 +176,7 @@ SearchResults SearchNode::runFuzzySearchOnSelf(const std::string& query) const
FuzzyMap m = fuzzyMatchRecursive(query, 0, 0, 0);
for (const std::pair<size_t, const SearchNode*>& p : m)
{
addResultsRecursive(result, p.first, p.second);
addResultsRecursive(&result, p.first, p.second);
}
// TODO: Currently all matches are added to the ordered set and get compared by their fullName for alphabetical
@@ -184,13 +184,18 @@ SearchResults SearchNode::runFuzzySearchOnSelf(const std::string& query) const
return result;
}
void SearchNode::addResultsRecursive(SearchResults& result, size_t weight, const SearchNode* node) const
void SearchNode::addResults(SearchResults* results, size_t weight, const SearchNode* node) const
{
result.insert(SearchResult(weight, node, this));
results->insert(SearchResult(weight, node, this));
}
void SearchNode::addResultsRecursive(SearchResults* results, size_t weight, const SearchNode* node) const
{
addResults(results, weight, node);
for (std::shared_ptr<SearchNode> n: node->m_nodes)
{
addResultsRecursive(result, weight, n.get());
addResultsRecursive(results, weight, n.get());
}
}
+2 -1
View File
@@ -46,7 +46,8 @@ public:
SearchResults runFuzzySearch(const std::string& query) const;
SearchResults runFuzzySearchOnSelf(const std::string& query) const;
void addResultsRecursive(SearchResults& result, size_t weight, const SearchNode* node) const;
void addResults(SearchResults* results, size_t weight, const SearchNode* node) const;
void addResultsRecursive(SearchResults* results, size_t weight, const SearchNode* node) const;
private:
typedef std::multimap<size_t, const SearchNode*> FuzzyMap;
+3 -1
View File
@@ -1,5 +1,7 @@
#include "data/search/SearchResult.h"
#include "utility/utilityString.h"
#include "data/search/SearchNode.h"
SearchResult::SearchResult()
@@ -20,5 +22,5 @@ bool SearchResult::operator()(const SearchResult& lhs, const SearchResult& rhs)
return lhs.weight > rhs.weight;
}
return lhs.node->getFullName() < rhs.node->getFullName();
return utility::toLowerCase(lhs.node->getFullName()) < utility::toLowerCase(rhs.node->getFullName());
}