ui: node type keywords to filter autocompletions or activate all nodes (issue #78)
* Fix history stack activating wrong symbol when aggregation was clicked
This commit is contained in:
@@ -94,32 +94,28 @@ void ActivationController::handleMessage(MessageSearch* message)
|
||||
{
|
||||
const std::vector<SearchMatch>& matches = message->getMatches();
|
||||
|
||||
for (const SearchMatch& match : matches)
|
||||
if (matches.size() && matches.back().searchType == SearchMatch::SEARCH_COMMAND)
|
||||
{
|
||||
if (match.searchType == SearchMatch::SEARCH_COMMAND)
|
||||
switch (matches.back().getCommandType())
|
||||
{
|
||||
SearchMatch::CommandType type = SearchMatch::getCommandType(match.getFullName());
|
||||
|
||||
switch (type)
|
||||
case SearchMatch::COMMAND_ALL:
|
||||
case SearchMatch::COMMAND_NODE_FILTER:
|
||||
{
|
||||
case SearchMatch::COMMAND_ALL:
|
||||
{
|
||||
MessageActivateAll().dispatchImmediately();
|
||||
return;
|
||||
}
|
||||
MessageActivateAll(message->filter).dispatchImmediately();
|
||||
return;
|
||||
}
|
||||
|
||||
case SearchMatch::COMMAND_ERROR:
|
||||
{
|
||||
MessageShowErrors(m_storageAccess->getErrorCount()).dispatch();
|
||||
MessageFlushUpdates().dispatch();
|
||||
return;
|
||||
}
|
||||
case SearchMatch::COMMAND_ERROR:
|
||||
{
|
||||
MessageShowErrors(m_storageAccess->getErrorCount()).dispatch();
|
||||
MessageFlushUpdates().dispatch();
|
||||
return;
|
||||
}
|
||||
|
||||
case SearchMatch::COMMAND_COLOR_SCHEME_TEST:
|
||||
{
|
||||
MessageColorSchemeTest().dispatchImmediately();
|
||||
return;
|
||||
}
|
||||
case SearchMatch::COMMAND_COLOR_SCHEME_TEST:
|
||||
{
|
||||
MessageColorSchemeTest().dispatchImmediately();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ void CodeController::handleMessage(MessageActivateAll* message)
|
||||
clear();
|
||||
|
||||
Project* currentProject = Application::getInstance()->getCurrentProject().get();
|
||||
if (!currentProject)
|
||||
if (!currentProject || message->filter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,15 +38,27 @@ void GraphController::handleMessage(MessageActivateAll* message)
|
||||
|
||||
m_dummyGraphNodes.clear();
|
||||
|
||||
createDummyGraphForTokenIdsAndSetActiveAndVisibility(std::vector<Id>(), m_storageAccess->getGraphForAll());
|
||||
if (message->filter)
|
||||
{
|
||||
createDummyGraphForTokenIdsAndSetActiveAndVisibility(
|
||||
std::vector<Id>(), m_storageAccess->getGraphForFilter(message->filter));
|
||||
|
||||
bundleNodesByType();
|
||||
addCharacterIndex();
|
||||
layoutNesting();
|
||||
layoutList();
|
||||
}
|
||||
else
|
||||
{
|
||||
createDummyGraphForTokenIdsAndSetActiveAndVisibility(std::vector<Id>(), m_storageAccess->getGraphForAll());
|
||||
|
||||
layoutNesting();
|
||||
assignBundleIds();
|
||||
layoutGraph();
|
||||
bundleNodesByType();
|
||||
|
||||
buildGraph(message, false, true, false);
|
||||
layoutNesting();
|
||||
assignBundleIds();
|
||||
layoutGraph();
|
||||
}
|
||||
|
||||
buildGraph(message, false, true, message->filter);
|
||||
}
|
||||
|
||||
void GraphController::handleMessage(MessageActivateTokens* message)
|
||||
|
||||
@@ -16,6 +16,15 @@ SearchController::~SearchController()
|
||||
|
||||
void SearchController::handleMessage(MessageActivateAll* message)
|
||||
{
|
||||
if (message->filter)
|
||||
{
|
||||
if (message->isReplayed())
|
||||
{
|
||||
getView()->setMatches(SearchMatch::createCommandsForFilter(message->filter));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
getView()->setMatches(std::vector<SearchMatch>(1, SearchMatch::createCommand(SearchMatch::COMMAND_ALL)));
|
||||
}
|
||||
|
||||
@@ -78,7 +87,7 @@ void SearchController::handleMessage(MessageSearchAutocomplete* message)
|
||||
}
|
||||
|
||||
LOG_INFO("autocomplete string: \"" + message->query + "\"");
|
||||
view->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query));
|
||||
view->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query, message->filter));
|
||||
}
|
||||
|
||||
void SearchController::handleMessage(MessageSearchFullText* message)
|
||||
|
||||
@@ -44,7 +44,8 @@ UndoRedoController::Command::Command(std::shared_ptr<MessageBase> message, Order
|
||||
|
||||
void UndoRedoController::handleMessage(MessageActivateAll* message)
|
||||
{
|
||||
if (sameMessageTypeAsLast(message))
|
||||
if (sameMessageTypeAsLast(message) &&
|
||||
static_cast<MessageActivateAll*>(lastMessage())->filter == message->filter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -595,7 +596,12 @@ SearchMatch UndoRedoController::getSearchMatchForMessage(MessageBase* message) c
|
||||
{
|
||||
if (message->getType() == MessageActivateAll::getStaticType())
|
||||
{
|
||||
return SearchMatch::createCommand(SearchMatch::COMMAND_ALL);
|
||||
SearchMatch match = SearchMatch::createCommand(SearchMatch::COMMAND_ALL);
|
||||
if (dynamic_cast<MessageActivateAll*>(message)->filter)
|
||||
{
|
||||
match.name = match.text = "filter"; // TODO: show filter names
|
||||
}
|
||||
return match;
|
||||
}
|
||||
else if (message->getType() == MessageActivateTokens::getStaticType())
|
||||
{
|
||||
@@ -604,6 +610,14 @@ SearchMatch UndoRedoController::getSearchMatchForMessage(MessageBase* message) c
|
||||
{
|
||||
return msg->searchMatches.front();
|
||||
}
|
||||
else if (msg->isAggregation)
|
||||
{
|
||||
SearchMatch match;
|
||||
match.name = match.text = "aggregation"; // TODO: show aggregation source and target
|
||||
match.searchType = SearchMatch::SEARCH_TOKEN;
|
||||
match.nodeType = Node::NODE_TYPE;
|
||||
return match;
|
||||
}
|
||||
}
|
||||
else if (message->getType() == MessageSearchFullText::getStaticType())
|
||||
{
|
||||
|
||||
@@ -278,6 +278,28 @@ bool HierarchyCache::nodeHasChildren(Id nodeId) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HierarchyCache::nodeIsVisible(Id nodeId) const
|
||||
{
|
||||
HierarchyNode* node = getNode(nodeId);
|
||||
if (node)
|
||||
{
|
||||
return node->isVisible();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HierarchyCache::nodeIsImplicit(Id nodeId) const
|
||||
{
|
||||
HierarchyNode* node = getNode(nodeId);
|
||||
if (node)
|
||||
{
|
||||
return node->isImplicit();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::tuple<Id, Id, std::vector<Id>>> HierarchyCache::getInheritanceEdgesForNodeId(
|
||||
Id nodeId, const std::set<Id>& nodeIds) const
|
||||
{
|
||||
|
||||
@@ -29,6 +29,8 @@ public:
|
||||
bool isChildOfVisibleNodeOrInvisible(Id nodeId) const;
|
||||
|
||||
bool nodeHasChildren(Id nodeId) const;
|
||||
bool nodeIsVisible(Id nodeId) const;
|
||||
bool nodeIsImplicit(Id nodeId) const;
|
||||
|
||||
std::vector<std::tuple<Id, Id, std::vector<Id>>> getInheritanceEdgesForNodeId(Id nodeId, const std::set<Id>& nodeIds) const;
|
||||
|
||||
|
||||
@@ -47,10 +47,11 @@ public:
|
||||
|
||||
virtual std::shared_ptr<SourceLocationCollection> getFullTextSearchLocations(
|
||||
const std::string& searchTerm, bool caseSensitive) const = 0;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const = 0;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query, Node::NodeTypeMask filter) const = 0;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& tokenIds) const = 0;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const = 0;
|
||||
virtual std::shared_ptr<Graph> getGraphForFilter(Node::NodeTypeMask filter) const = 0;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(
|
||||
const std::vector<Id>& tokenIds, const std::vector<Id>& expandedNodeIds, bool* isActiveNamespace = nullptr) const = 0;
|
||||
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const = 0;
|
||||
|
||||
@@ -125,11 +125,11 @@ std::shared_ptr<SourceLocationCollection> StorageAccessProxy::getFullTextSearchL
|
||||
return std::make_shared<SourceLocationCollection>();
|
||||
}
|
||||
|
||||
std::vector<SearchMatch> StorageAccessProxy::getAutocompletionMatches(const std::string& query) const
|
||||
std::vector<SearchMatch> StorageAccessProxy::getAutocompletionMatches(const std::string& query, Node::NodeTypeMask filter) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getAutocompletionMatches(query);
|
||||
return m_subject->getAutocompletionMatches(query, filter);
|
||||
}
|
||||
|
||||
return std::vector<SearchMatch>();
|
||||
@@ -155,6 +155,16 @@ std::shared_ptr<Graph> StorageAccessProxy::getGraphForAll() const
|
||||
return std::make_shared<Graph>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> StorageAccessProxy::getGraphForFilter(Node::NodeTypeMask filter) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getGraphForFilter(filter);
|
||||
}
|
||||
|
||||
return std::make_shared<Graph>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> StorageAccessProxy::getGraphForActiveTokenIds(
|
||||
const std::vector<Id>& tokenIds, const std::vector<Id>& expandedNodeIds, bool* isActiveNamespace) const
|
||||
{
|
||||
|
||||
@@ -33,10 +33,11 @@ public:
|
||||
|
||||
virtual std::shared_ptr<SourceLocationCollection> getFullTextSearchLocations(
|
||||
const std::string& searchTerm, bool caseSensitive) const;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query, Node::NodeTypeMask filter) const;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const;
|
||||
virtual std::shared_ptr<Graph> getGraphForFilter(Node::NodeTypeMask filter) const;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(
|
||||
const std::vector<Id>& tokenIds, const std::vector<Id>& expandedNodeIds, bool* isActiveNamespace = nullptr) const;
|
||||
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const;
|
||||
|
||||
@@ -73,6 +73,20 @@ std::string Node::getReadableTypeString(NodeType type)
|
||||
return "";
|
||||
}
|
||||
|
||||
Node::NodeType Node::getTypeForReadableTypeString(const std::string str)
|
||||
{
|
||||
for (Node::NodeTypeMask mask = 1; mask <= NODE_MAX_VALUE; mask *= 2)
|
||||
{
|
||||
Node::NodeType type = intToType(mask);
|
||||
if (getReadableTypeString(type) == str)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return NODE_NON_INDEXED;
|
||||
}
|
||||
|
||||
int Node::typeToInt(NodeType type)
|
||||
{
|
||||
return type;
|
||||
|
||||
@@ -46,11 +46,14 @@ public:
|
||||
|
||||
NODE_FILE = 0x20000,
|
||||
NODE_MACRO = 0x40000,
|
||||
NODE_UNION = 0x80000
|
||||
NODE_UNION = 0x80000,
|
||||
|
||||
NODE_MAX_VALUE = NODE_UNION
|
||||
};
|
||||
|
||||
static std::string getUnderscoredTypeString(NodeType type);
|
||||
static std::string getReadableTypeString(NodeType type);
|
||||
static Node::NodeType getTypeForReadableTypeString(const std::string str);
|
||||
|
||||
static int typeToInt(NodeType type);
|
||||
static NodeType intToType(int value);
|
||||
|
||||
@@ -56,6 +56,27 @@ SearchMatch SearchMatch::createCommand(CommandType type)
|
||||
return match;
|
||||
}
|
||||
|
||||
std::vector<SearchMatch> SearchMatch::createCommandsForFilter(Node::NodeTypeMask filter)
|
||||
{
|
||||
std::vector<SearchMatch> matches;
|
||||
|
||||
for (Node::NodeTypeMask type = 1; type <= filter; type *= 2)
|
||||
{
|
||||
if (type & filter)
|
||||
{
|
||||
SearchMatch match;
|
||||
match.name = Node::getReadableTypeString(Node::intToType(type));
|
||||
match.text = match.name;
|
||||
match.typeName = "filter";
|
||||
match.searchType = SEARCH_COMMAND;
|
||||
match.nodeType = Node::intToType(type);
|
||||
matches.push_back(match);
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
std::string SearchMatch::getCommandName(CommandType type)
|
||||
{
|
||||
switch (type)
|
||||
@@ -64,6 +85,8 @@ std::string SearchMatch::getCommandName(CommandType type)
|
||||
return "overview";
|
||||
case COMMAND_ERROR:
|
||||
return "error";
|
||||
case COMMAND_NODE_FILTER:
|
||||
return "node_filter";
|
||||
case COMMAND_COLOR_SCHEME_TEST:
|
||||
return "color_scheme_test";
|
||||
}
|
||||
@@ -71,26 +94,9 @@ std::string SearchMatch::getCommandName(CommandType type)
|
||||
return "none";
|
||||
}
|
||||
|
||||
SearchMatch::CommandType SearchMatch::getCommandType(const std::string& name)
|
||||
{
|
||||
if (name == "overview")
|
||||
{
|
||||
return COMMAND_ALL;
|
||||
}
|
||||
else if (name == "error")
|
||||
{
|
||||
return COMMAND_ERROR;
|
||||
}
|
||||
else if (name == "color_scheme_test")
|
||||
{
|
||||
return COMMAND_COLOR_SCHEME_TEST;
|
||||
}
|
||||
|
||||
return COMMAND_ALL;
|
||||
}
|
||||
|
||||
SearchMatch::SearchMatch()
|
||||
: typeName("")
|
||||
, nodeType(Node::NODE_NON_INDEXED)
|
||||
, searchType(SEARCH_NONE)
|
||||
, hasChildren(false)
|
||||
{
|
||||
@@ -100,6 +106,7 @@ SearchMatch::SearchMatch(const std::string& query)
|
||||
: name(query)
|
||||
, text(query)
|
||||
, typeName("")
|
||||
, nodeType(Node::NODE_NON_INDEXED)
|
||||
, searchType(SEARCH_NONE)
|
||||
, hasChildren(false)
|
||||
{
|
||||
@@ -193,6 +200,11 @@ bool SearchMatch::isValid() const
|
||||
return searchType != SEARCH_NONE;
|
||||
}
|
||||
|
||||
bool SearchMatch::isFilterCommand() const
|
||||
{
|
||||
return searchType == SEARCH_COMMAND && getCommandType() == COMMAND_NODE_FILTER;
|
||||
}
|
||||
|
||||
void SearchMatch::print(std::ostream& ostream) const
|
||||
{
|
||||
ostream << name << std::endl << '\t';
|
||||
@@ -229,3 +241,21 @@ std::string SearchMatch::getSearchTypeName() const
|
||||
{
|
||||
return getSearchTypeName(searchType);
|
||||
}
|
||||
|
||||
SearchMatch::CommandType SearchMatch::getCommandType() const
|
||||
{
|
||||
if (name == "overview")
|
||||
{
|
||||
return COMMAND_ALL;
|
||||
}
|
||||
else if (name == "error")
|
||||
{
|
||||
return COMMAND_ERROR;
|
||||
}
|
||||
else if (name == "color_scheme_test")
|
||||
{
|
||||
return COMMAND_COLOR_SCHEME_TEST;
|
||||
}
|
||||
|
||||
return COMMAND_NODE_FILTER;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ struct SearchMatch
|
||||
{
|
||||
COMMAND_ALL,
|
||||
COMMAND_ERROR,
|
||||
COMMAND_NODE_FILTER,
|
||||
COMMAND_COLOR_SCHEME_TEST
|
||||
};
|
||||
|
||||
@@ -33,8 +34,8 @@ struct SearchMatch
|
||||
static std::string searchMatchesToString(const std::vector<SearchMatch>& matches);
|
||||
|
||||
static SearchMatch createCommand(CommandType type);
|
||||
static std::vector<SearchMatch> createCommandsForFilter(Node::NodeTypeMask filter);
|
||||
static std::string getCommandName(CommandType type);
|
||||
static CommandType getCommandType(const std::string& name);
|
||||
|
||||
static const char FULLTEXT_SEARCH_CHARACTER = '?';
|
||||
|
||||
@@ -47,12 +48,14 @@ struct SearchMatch
|
||||
size_t getTextSizeForSorting(const std::string* str) const;
|
||||
|
||||
bool isValid() const;
|
||||
bool isFilterCommand() const;
|
||||
|
||||
void print(std::ostream& ostream) const;
|
||||
|
||||
std::string getFullName() const;
|
||||
std::string getNodeTypeAsUnderscoredString() const;
|
||||
std::string getSearchTypeName() const;
|
||||
CommandType getCommandType() const;
|
||||
|
||||
std::string name;
|
||||
std::vector<Id> tokenIds;
|
||||
|
||||
@@ -31,7 +31,30 @@ PersistentStorage::PersistentStorage(const FilePath& dbPath, const FilePath& boo
|
||||
{
|
||||
m_commandIndex.addNode(0, SearchMatch::getCommandName(SearchMatch::COMMAND_ALL));
|
||||
m_commandIndex.addNode(0, SearchMatch::getCommandName(SearchMatch::COMMAND_ERROR));
|
||||
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_NON_INDEXED));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_TYPE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_BUILTIN_TYPE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_NAMESPACE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_PACKAGE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_STRUCT));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_CLASS));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_INTERFACE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_GLOBAL_VARIABLE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_FIELD));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_FUNCTION));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_METHOD));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_ENUM));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_ENUM_CONSTANT));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_TYPEDEF));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_TEMPLATE_PARAMETER_TYPE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_TYPE_PARAMETER));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_FILE));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_MACRO));
|
||||
m_commandIndex.addNode(0, Node::getReadableTypeString(Node::NODE_UNION));
|
||||
|
||||
// m_commandIndex.addNode(0, SearchMatch::getCommandName(SearchMatch::COMMAND_COLOR_SCHEME_TEST));
|
||||
|
||||
m_commandIndex.finishSetup();
|
||||
}
|
||||
|
||||
@@ -558,7 +581,7 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getFullTextSearchLo
|
||||
return collection;
|
||||
}
|
||||
|
||||
std::vector<SearchMatch> PersistentStorage::getAutocompletionMatches(const std::string& query) const
|
||||
std::vector<SearchMatch> PersistentStorage::getAutocompletionMatches(const std::string& query, Node::NodeTypeMask filter) const
|
||||
{
|
||||
TRACE();
|
||||
|
||||
@@ -568,9 +591,18 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionMatches(const std::
|
||||
|
||||
// create SearchMatches
|
||||
std::vector<SearchMatch> matches;
|
||||
utility::append(matches, getAutocompletionSymbolMatches(query, maxResultsCount));
|
||||
utility::append(matches, getAutocompletionFileMatches(query, maxResultsCount));
|
||||
utility::append(matches, getAutocompletionCommandMatches(query));
|
||||
|
||||
if (!filter || (filter & ~Node::NODE_FILE))
|
||||
{
|
||||
utility::append(matches, getAutocompletionSymbolMatches(query, filter, maxResultsCount));
|
||||
}
|
||||
|
||||
if (!filter || (filter & Node::NODE_FILE))
|
||||
{
|
||||
utility::append(matches, getAutocompletionFileMatches(query, maxResultsCount));
|
||||
}
|
||||
|
||||
utility::append(matches, getAutocompletionCommandMatches(query, filter));
|
||||
|
||||
std::set<SearchMatch> matchesSet;
|
||||
for (SearchMatch& match : matches)
|
||||
@@ -592,7 +624,7 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionMatches(const std::
|
||||
}
|
||||
|
||||
std::vector<SearchMatch> PersistentStorage::getAutocompletionSymbolMatches(
|
||||
const std::string& query, size_t maxResultsCount) const
|
||||
const std::string& query, Node::NodeTypeMask filter, size_t maxResultsCount) const
|
||||
{
|
||||
// search in indices
|
||||
std::vector<SearchResult> results = m_symbolIndex.search(query, maxResultsCount, maxResultsCount);
|
||||
@@ -632,7 +664,7 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionSymbolMatches(
|
||||
{
|
||||
match.tokenIds.push_back(elementId);
|
||||
|
||||
if (!match.hasChildren)
|
||||
if (!match.hasChildren && !filter) // TODO: apply filter to children
|
||||
{
|
||||
match.hasChildren = m_hierarchyCache.nodeHasChildren(elementId);
|
||||
}
|
||||
@@ -644,6 +676,11 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionSymbolMatches(
|
||||
}
|
||||
}
|
||||
|
||||
if (filter && !(filter & Node::intToType(firstNode->type)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
match.name = result.text;
|
||||
match.text = result.text;
|
||||
|
||||
@@ -705,7 +742,8 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionFileMatches(const s
|
||||
return matches;
|
||||
}
|
||||
|
||||
std::vector<SearchMatch> PersistentStorage::getAutocompletionCommandMatches(const std::string& query) const
|
||||
std::vector<SearchMatch> PersistentStorage::getAutocompletionCommandMatches(
|
||||
const std::string& query, Node::NodeTypeMask filter) const
|
||||
{
|
||||
// search in indices
|
||||
std::vector<SearchResult> results = m_commandIndex.search(query, 0);
|
||||
@@ -727,7 +765,16 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionCommandMatches(cons
|
||||
match.searchType = SearchMatch::SEARCH_COMMAND;
|
||||
match.typeName = "command";
|
||||
|
||||
matches.push_back(match);
|
||||
if (match.getCommandType() == SearchMatch::COMMAND_NODE_FILTER)
|
||||
{
|
||||
match.nodeType = Node::getTypeForReadableTypeString(match.name);
|
||||
match.typeName = "filter";
|
||||
}
|
||||
|
||||
if (!filter || (match.getCommandType() == SearchMatch::COMMAND_NODE_FILTER && !(filter & match.nodeType)))
|
||||
{
|
||||
matches.push_back(match);
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
@@ -809,6 +856,38 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForAll() const
|
||||
return graph;
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> PersistentStorage::getGraphForFilter(Node::NodeTypeMask filter) const
|
||||
{
|
||||
TRACE();
|
||||
|
||||
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
|
||||
|
||||
std::vector<Id> tokenIds;
|
||||
for (StorageNode& node: m_sqliteIndexStorage.getAll<StorageNode>())
|
||||
{
|
||||
if ((filter & Node::intToType(node.type)))
|
||||
{
|
||||
auto it = m_symbolDefinitionKinds.find(node.id);
|
||||
if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT)
|
||||
{
|
||||
tokenIds.push_back(node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!filter || (filter & Node::NODE_FILE))
|
||||
{
|
||||
for (const auto& p : m_fileNodePaths)
|
||||
{
|
||||
tokenIds.push_back(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
addNodesWithParentsAndEdgesToGraph(tokenIds, std::vector<Id>(), graph.get(), false);
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> PersistentStorage::getGraphForActiveTokenIds(
|
||||
const std::vector<Id>& tokenIds, const std::vector<Id>& expandedNodeIds, bool* isActiveNamespace) const
|
||||
{
|
||||
@@ -918,7 +997,7 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForActiveTokenIds(
|
||||
}
|
||||
else
|
||||
{
|
||||
addNodesWithParentsAndEdgesToGraph(nodeIds, edgeIds, graph);
|
||||
addNodesWithParentsAndEdgesToGraph(nodeIds, edgeIds, graph, true);
|
||||
}
|
||||
|
||||
if (addAggregations)
|
||||
@@ -1035,7 +1114,7 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForTrail(
|
||||
|
||||
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
|
||||
|
||||
addNodesWithParentsAndEdgesToGraph(utility::toVector(nodeIds), utility::toVector(edgeIds), graph.get());
|
||||
addNodesWithParentsAndEdgesToGraph(utility::toVector(nodeIds), utility::toVector(edgeIds), graph.get(), false);
|
||||
addComponentAccessToGraph(graph.get());
|
||||
|
||||
return graph;
|
||||
@@ -2128,7 +2207,7 @@ void PersistentStorage::addEdgesToGraph(const std::vector<Id>& newEdgeIds, Graph
|
||||
}
|
||||
|
||||
void PersistentStorage::addNodesWithParentsAndEdgesToGraph(
|
||||
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graph
|
||||
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graph, bool addChildCount
|
||||
) const
|
||||
{
|
||||
TRACE();
|
||||
@@ -2153,7 +2232,7 @@ void PersistentStorage::addNodesWithParentsAndEdgesToGraph(
|
||||
|
||||
allNodeIds.insert(parentNodeIds.begin(), parentNodeIds.end());
|
||||
|
||||
addNodesToGraph(utility::toVector(allNodeIds), graph, true);
|
||||
addNodesToGraph(utility::toVector(allNodeIds), graph, addChildCount);
|
||||
addEdgesToGraph(utility::toVector(allEdgeIds), graph);
|
||||
}
|
||||
|
||||
@@ -2231,7 +2310,7 @@ void PersistentStorage::addAggregationEdgesToGraph(
|
||||
nodeIdsToAdd.push_back(aggregationTargetNodeId);
|
||||
}
|
||||
}
|
||||
addNodesWithParentsAndEdgesToGraph(nodeIdsToAdd, std::vector<Id>(), graph);
|
||||
addNodesWithParentsAndEdgesToGraph(nodeIdsToAdd, std::vector<Id>(), graph, true);
|
||||
|
||||
// create aggregation edges between parents and active node
|
||||
Node* sourceNode = graph->getNodeById(nodeId);
|
||||
|
||||
@@ -87,13 +87,15 @@ public:
|
||||
virtual std::shared_ptr<SourceLocationCollection> getFullTextSearchLocations(
|
||||
const std::string& searchTerm, bool caseSensitive) const;
|
||||
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const;
|
||||
std::vector<SearchMatch> getAutocompletionSymbolMatches(const std::string& query, size_t maxResultsCount) const;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query, Node::NodeTypeMask filter) const;
|
||||
std::vector<SearchMatch> getAutocompletionSymbolMatches(
|
||||
const std::string& query, Node::NodeTypeMask filter, size_t maxResultsCount) const;
|
||||
std::vector<SearchMatch> getAutocompletionFileMatches(const std::string& query, size_t maxResultsCount) const;
|
||||
std::vector<SearchMatch> getAutocompletionCommandMatches(const std::string& query) const;
|
||||
std::vector<SearchMatch> getAutocompletionCommandMatches(const std::string& query, Node::NodeTypeMask filter) const;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& elementIds) const;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const;
|
||||
virtual std::shared_ptr<Graph> getGraphForFilter(Node::NodeTypeMask filter) const;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(
|
||||
const std::vector<Id>& tokenIds, const std::vector<Id>& expandedNodeIds, bool* isActiveNamespace = nullptr) const;
|
||||
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const;
|
||||
@@ -163,7 +165,7 @@ private:
|
||||
void addNodesToGraph(const std::vector<Id>& nodeIds, Graph* graph, bool addChildCount) const;
|
||||
void addEdgesToGraph(const std::vector<Id>& edgeIds, Graph* graph) const;
|
||||
void addNodesWithParentsAndEdgesToGraph(
|
||||
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graph) const;
|
||||
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graphh, bool addChildCount) const;
|
||||
|
||||
void addAggregationEdgesToGraph(const Id nodeId, const std::vector<StorageEdge>& edgesToAggregate, Graph* graph) const;
|
||||
void addComponentAccessToGraph(Graph* graph) const;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef MESSAGE_ACTIVATE_ALL_H
|
||||
#define MESSAGE_ACTIVATE_ALL_H
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
#include "utility/messaging/Message.h"
|
||||
|
||||
class MessageActivateAll
|
||||
: public Message<MessageActivateAll>
|
||||
{
|
||||
public:
|
||||
MessageActivateAll()
|
||||
MessageActivateAll(Node::NodeTypeMask filter = 0)
|
||||
: filter(filter)
|
||||
{
|
||||
setIsParallel(true);
|
||||
}
|
||||
@@ -16,6 +18,8 @@ public:
|
||||
{
|
||||
return "MessageActivateAll";
|
||||
}
|
||||
|
||||
Node::NodeTypeMask filter;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_ACTIVATE_ALL_H
|
||||
|
||||
@@ -9,8 +9,9 @@ class MessageSearch
|
||||
: public Message<MessageSearch>
|
||||
{
|
||||
public:
|
||||
MessageSearch(const std::vector<SearchMatch>& matches)
|
||||
MessageSearch(const std::vector<SearchMatch>& matches, Node::NodeTypeMask filter = 0)
|
||||
: isFromSearch(true)
|
||||
, filter(filter)
|
||||
, m_matches(matches)
|
||||
{
|
||||
}
|
||||
@@ -71,6 +72,7 @@ public:
|
||||
}
|
||||
|
||||
bool isFromSearch;
|
||||
Node::NodeTypeMask filter;
|
||||
|
||||
private:
|
||||
const std::vector<SearchMatch> m_matches;
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#ifndef MESSAGE_SEARCH_AUTOCOMPLETE_H
|
||||
#define MESSAGE_SEARCH_AUTOCOMPLETE_H
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
#include "utility/messaging/Message.h"
|
||||
|
||||
class MessageSearchAutocomplete: public Message<MessageSearchAutocomplete>
|
||||
class MessageSearchAutocomplete
|
||||
: public Message<MessageSearchAutocomplete>
|
||||
{
|
||||
public:
|
||||
MessageSearchAutocomplete(const std::string& query)
|
||||
MessageSearchAutocomplete(const std::string& query, Node::NodeTypeMask filter)
|
||||
: query(query)
|
||||
, filter(filter)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -18,10 +21,11 @@ public:
|
||||
|
||||
virtual void print(std::ostream& os) const
|
||||
{
|
||||
os << query;
|
||||
os << query << " " << filter;
|
||||
}
|
||||
|
||||
const std::string query;
|
||||
const Node::NodeTypeMask filter;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_SEARCH_AUTOCOMPLETE_H
|
||||
|
||||
@@ -144,12 +144,10 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt
|
||||
|
||||
// define highlight colors
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
// QColor fillColor("#FFFFFF");
|
||||
QColor fillColor(0xFF, 0xFF, 0xFF);
|
||||
// QColor textColor("#000000");
|
||||
QColor textColor(0, 0, 0);
|
||||
|
||||
if (type.size() && type != "command")
|
||||
if (type.size() && type != "command" && type != "filter")
|
||||
{
|
||||
const GraphViewStyle::NodeColor& nodeColor = GraphViewStyle::getNodeColor(Node::getUnderscoredTypeString(nodeType), false);
|
||||
fillColor = QColor(nodeColor.fill.c_str());
|
||||
|
||||
@@ -32,6 +32,11 @@ void QtSmartSearchBox::search()
|
||||
{
|
||||
editTextToElement();
|
||||
|
||||
if (!m_matches.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Do a fulltext search if no autocompletion match was selected for this match
|
||||
if (m_matches.size() == 1)
|
||||
{
|
||||
@@ -55,7 +60,7 @@ void QtSmartSearchBox::search()
|
||||
|
||||
std::vector<SearchMatch> matches = utility::toVector(m_matches);
|
||||
|
||||
MessageSearch(matches).dispatch();
|
||||
MessageSearch(matches, getMatchFilter()).dispatch();
|
||||
}
|
||||
|
||||
void QtSmartSearchBox::fullTextSearch()
|
||||
@@ -83,7 +88,6 @@ void QtSmartSearchBox::fullTextSearch()
|
||||
|
||||
QtSmartSearchBox::QtSmartSearchBox(QWidget* parent)
|
||||
: QLineEdit(parent)
|
||||
, m_allowMultipleElements(false)
|
||||
, m_allowTextChange(false)
|
||||
, m_cursorIndex(0)
|
||||
, m_shiftKeyDown(false)
|
||||
@@ -176,20 +180,20 @@ bool QtSmartSearchBox::event(QEvent *event)
|
||||
{
|
||||
if (m_completer->popup()->isVisible())
|
||||
{
|
||||
if (m_highlightedMatch.hasChildren)
|
||||
if (m_highlightedMatch.isFilterCommand())
|
||||
{
|
||||
addMatchAndUpdate(m_highlightedMatch);
|
||||
}
|
||||
else if (m_highlightedMatch.hasChildren)
|
||||
{
|
||||
setEditText((m_highlightedMatch.getFullName() + nameDelimiterTypeToString(m_highlightedMatch.delimiter)).c_str());
|
||||
requestAutoCompletions();
|
||||
}
|
||||
else
|
||||
{
|
||||
setEditText(m_highlightedMatch.getFullName().c_str());
|
||||
requestAutoCompletions();
|
||||
}
|
||||
|
||||
requestAutoCompletions();
|
||||
}
|
||||
else if (m_allowMultipleElements)
|
||||
{
|
||||
requestAutoCompletions();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -525,7 +529,7 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
|
||||
}
|
||||
}
|
||||
|
||||
if (match.name.size() && !m_allowMultipleElements)
|
||||
if (match.name.size() && lastMatchIsNoFilter())
|
||||
{
|
||||
if (m_matches.size())
|
||||
{
|
||||
@@ -544,7 +548,7 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
|
||||
layoutElements();
|
||||
}
|
||||
|
||||
if (match.name.size() || m_elements.size())
|
||||
if (match.name.size())
|
||||
{
|
||||
requestAutoCompletions();
|
||||
}
|
||||
@@ -665,7 +669,7 @@ void QtSmartSearchBox::addMatch(const SearchMatch& match)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_allowMultipleElements)
|
||||
if (lastMatchIsNoFilter())
|
||||
{
|
||||
clearMatches();
|
||||
}
|
||||
@@ -743,6 +747,10 @@ void QtSmartSearchBox::updateElements()
|
||||
{
|
||||
std::string name = match.getFullName();
|
||||
name = utility::replace(name, "&", "&&");
|
||||
if (match.isFilterCommand())
|
||||
{
|
||||
name += ':';
|
||||
}
|
||||
|
||||
std::shared_ptr<QtSearchElement> element = std::make_shared<QtSearchElement>(QString::fromStdString(name), this);
|
||||
m_elements.push_back(element);
|
||||
@@ -964,7 +972,7 @@ void QtSmartSearchBox::requestAutoCompletions()
|
||||
{
|
||||
if (text().size() && !text().startsWith(SearchMatch::FULLTEXT_SEARCH_CHARACTER))
|
||||
{
|
||||
MessageSearchAutocomplete(text().toStdString()).dispatch();
|
||||
MessageSearchAutocomplete(text().toStdString(), getMatchFilter()).dispatch();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -986,3 +994,27 @@ std::deque<SearchMatch> QtSmartSearchBox::getMatchesForInput(const std::string&
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
Node::NodeTypeMask QtSmartSearchBox::getMatchFilter() const
|
||||
{
|
||||
Node::NodeTypeMask filter = 0;
|
||||
|
||||
for (const SearchMatch& match : m_matches)
|
||||
{
|
||||
if (match.isFilterCommand())
|
||||
{
|
||||
filter |= match.nodeType;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
bool QtSmartSearchBox::lastMatchIsNoFilter() const
|
||||
{
|
||||
return !m_matches.size() || !m_matches.back().isFilterCommand();
|
||||
}
|
||||
|
||||
@@ -99,7 +99,8 @@ private:
|
||||
|
||||
std::deque<SearchMatch> getMatchesForInput(const std::string& text) const;
|
||||
|
||||
bool m_allowMultipleElements;
|
||||
Node::NodeTypeMask getMatchFilter() const;
|
||||
bool lastMatchIsNoFilter() const;
|
||||
|
||||
bool m_allowTextChange;
|
||||
QString m_oldText;
|
||||
|
||||
Reference in New Issue
Block a user