diff --git a/src/app/qt/element/QtSearchBar.cpp b/src/app/qt/element/QtSearchBar.cpp index 9be2f111..a0770cc9 100644 --- a/src/app/qt/element/QtSearchBar.cpp +++ b/src/app/qt/element/QtSearchBar.cpp @@ -60,14 +60,9 @@ QSize QtSearchBar::sizeHint() const return QSize(400, 100); } -void QtSearchBar::setText(const std::string& text) +void QtSearchBar::setMatches(const std::deque& matches) { - m_searchBox->setQuery(text); -} - -void QtSearchBar::setMatch(const SearchMatch& match) -{ - m_searchBox->setQuery(match); + m_searchBox->setMatches(matches); } void QtSearchBar::setFocus() diff --git a/src/app/qt/element/QtSearchBar.h b/src/app/qt/element/QtSearchBar.h index d4f489e7..f2f71d62 100644 --- a/src/app/qt/element/QtSearchBar.h +++ b/src/app/qt/element/QtSearchBar.h @@ -22,8 +22,7 @@ public: virtual QSize sizeHint() const; - void setText(const std::string& text); - void setMatch(const SearchMatch& match); + void setMatches(const std::deque& matches); void setFocus(); void setAutocompletionList(const std::vector& autocompletionList); diff --git a/src/app/qt/element/QtSmartSearchBox.cpp b/src/app/qt/element/QtSmartSearchBox.cpp index 188620e5..1b2de8eb 100644 --- a/src/app/qt/element/QtSmartSearchBox.cpp +++ b/src/app/qt/element/QtSmartSearchBox.cpp @@ -33,8 +33,10 @@ void QtQueryElement::onChecked(bool) void QtSmartSearchBox::search() { editTextToElement(); - LOG_INFO(utility::join(SearchMatch::searchMatchDequeToStringDeque(m_tokens), "")+ text().toStdString()); - MessageSearch(utility::join(SearchMatch::searchMatchDequeToStringDeque(m_tokens), "") + text().toStdString()).dispatch(); + + LOG_INFO_STREAM(<< "Search query: " << SearchMatch::searchMatchDequeToString(m_tokens) << text().toStdString()); + + MessageSearch(m_tokens).dispatch(); } QtSmartSearchBox::QtSmartSearchBox(QWidget* parent) @@ -80,21 +82,16 @@ void QtSmartSearchBox::setAutocompletionList(const std::vector& aut } } -void QtSmartSearchBox::setQuery(const SearchMatch& match) +void QtSmartSearchBox::setMatches(const std::deque& matches) { - clearLineEdit(); - m_tokens.clear(); - m_tokens.push_back(match); - m_cursorIndex = m_tokens.size(); - updateElements(); -} + if (SearchMatch::searchMatchDequeToString(matches) == SearchMatch::searchMatchDequeToString(m_tokens)) + { + return; + } -void QtSmartSearchBox::setQuery(const std::string& text) -{ clearLineEdit(); - m_tokens = SearchMatch::stringDequeToSearchMatchDeque(QueryTree::tokenizeQuery(text)); + m_tokens = matches; m_cursorIndex = m_tokens.size(); - updateElements(); } diff --git a/src/app/qt/element/QtSmartSearchBox.h b/src/app/qt/element/QtSmartSearchBox.h index 9443fe29..37b9883f 100644 --- a/src/app/qt/element/QtSmartSearchBox.h +++ b/src/app/qt/element/QtSmartSearchBox.h @@ -39,8 +39,7 @@ public: virtual ~QtSmartSearchBox(); void setAutocompletionList(const std::vector& autocompletionList); - void setQuery(const SearchMatch& match); - void setQuery(const std::string& text); + void setMatches(const std::deque& matches); void setFocus(); protected: diff --git a/src/app/qt/view/QtCodeView.cpp b/src/app/qt/view/QtCodeView.cpp index 0576e1d5..3e304993 100644 --- a/src/app/qt/view/QtCodeView.cpp +++ b/src/app/qt/view/QtCodeView.cpp @@ -75,6 +75,7 @@ void QtCodeView::defocusToken() void QtCodeView::doRefreshView() { setStyleSheet(m_widget); + m_widget->clearCodeSnippets(); } void QtCodeView::doShowCodeSnippets(const std::vector& snippets) diff --git a/src/app/qt/view/QtGraphView.cpp b/src/app/qt/view/QtGraphView.cpp index 90833c16..60882a54 100644 --- a/src/app/qt/view/QtGraphView.cpp +++ b/src/app/qt/view/QtGraphView.cpp @@ -65,6 +65,7 @@ void QtGraphView::initView() void QtGraphView::refreshView() { + clear(); resizeView(); } diff --git a/src/app/qt/view/QtSearchView.cpp b/src/app/qt/view/QtSearchView.cpp index 184f4592..c6c4975c 100644 --- a/src/app/qt/view/QtSearchView.cpp +++ b/src/app/qt/view/QtSearchView.cpp @@ -7,8 +7,7 @@ QtSearchView::QtSearchView(ViewLayout* viewLayout) : SearchView(viewLayout) , m_refreshViewFunctor(std::bind(&QtSearchView::doRefreshView, this)) - , m_setTextFunctor(std::bind(&QtSearchView::doSetText, this, std::placeholders::_1)) - , m_setMatchFunctor(std::bind(&QtSearchView::doSetMatch, this, std::placeholders::_1)) + , m_setMatchesFunctor(std::bind(&QtSearchView::doSetMatches, this, std::placeholders::_1)) , m_setFocusFunctor(std::bind(&QtSearchView::doSetFocus, this)) , m_setAutocompletionListFunctor(std::bind(&QtSearchView::doSetAutocompletionList, this, std::placeholders::_1)) { @@ -34,14 +33,9 @@ void QtSearchView::refreshView() m_refreshViewFunctor(); } -void QtSearchView::setText(const std::string& text) +void QtSearchView::setMatches(const std::deque& matches) { - m_setTextFunctor(text); -} - -void QtSearchView::setMatch(const SearchMatch& match) -{ - m_setMatchFunctor(match); + m_setMatchesFunctor(matches); } void QtSearchView::setFocus() @@ -57,16 +51,12 @@ void QtSearchView::setAutocompletionList(const std::vector& autocom void QtSearchView::doRefreshView() { setStyleSheet(); + m_widget->setMatches(std::deque()); } -void QtSearchView::doSetMatch(const SearchMatch& match) +void QtSearchView::doSetMatches(const std::deque& matches) { - m_widget->setMatch(match); -} - -void QtSearchView::doSetText(const std::string& text) -{ - m_widget->setText(text); + m_widget->setMatches(matches); } void QtSearchView::doSetFocus() diff --git a/src/app/qt/view/QtSearchView.h b/src/app/qt/view/QtSearchView.h index e1067366..fd1ddd50 100644 --- a/src/app/qt/view/QtSearchView.h +++ b/src/app/qt/view/QtSearchView.h @@ -19,23 +19,20 @@ public: virtual void refreshView(); // SearchView implementation - virtual void setText(const std::string& text); - virtual void setMatch(const SearchMatch& match); + virtual void setMatches(const std::deque& matches); virtual void setFocus(); virtual void setAutocompletionList(const std::vector& autocompletionList); private: void doRefreshView(); - void doSetMatch(const SearchMatch& match); - void doSetText(const std::string& text); + void doSetMatches(const std::deque& matches); void doSetFocus(); void doSetAutocompletionList(const std::vector& autocompletionList); void setStyleSheet(); QtThreadedFunctor<> m_refreshViewFunctor; - QtThreadedFunctor m_setTextFunctor; - QtThreadedFunctor m_setMatchFunctor; + QtThreadedFunctor&> m_setMatchesFunctor; QtThreadedFunctor<> m_setFocusFunctor; QtThreadedFunctor&> m_setAutocompletionListFunctor; diff --git a/src/app/qt/view/graphElements/QtGraphEdge.cpp b/src/app/qt/view/graphElements/QtGraphEdge.cpp index 4e6f95f9..64d5581b 100644 --- a/src/app/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/app/qt/view/graphElements/QtGraphEdge.cpp @@ -2,7 +2,7 @@ #include -#include "utility/messaging/type/MessageActivateTokens.h" +#include "utility/messaging/type/MessageActivateEdge.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" #include "utility/messaging/type/MessageGraphNodeBundleSplit.h" @@ -123,16 +123,9 @@ void QtGraphEdge::onClick() { MessageGraphNodeBundleSplit(m_target.lock()->getTokenId()).dispatch(); } - else if (getData()->isType(Edge::EDGE_AGGREGATION)) - { - const std::set& ids = getData()->getComponent()->getAggregationIds(); - MessageActivateTokens(std::vector(ids.begin(), ids.end())).dispatch(); - } else { - MessageActivateTokens message(getData()->getId()); - message.isEdge = true; - message.dispatch(); + MessageActivateEdge(getData()->getId(), getData()->getType(), getData()->getName()).dispatch(); } } diff --git a/src/app/qt/view/graphElements/QtGraphNodeData.cpp b/src/app/qt/view/graphElements/QtGraphNodeData.cpp index 8d6f7beb..c9e9f278 100644 --- a/src/app/qt/view/graphElements/QtGraphNodeData.cpp +++ b/src/app/qt/view/graphElements/QtGraphNodeData.cpp @@ -1,6 +1,6 @@ #include "qt/view/graphElements/QtGraphNodeData.h" -#include "utility/messaging/type/MessageActivateTokens.h" +#include "utility/messaging/type/MessageActivateNode.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" #include "utility/messaging/type/MessageGraphNodeMove.h" @@ -37,7 +37,7 @@ void QtGraphNodeData::onClick() { if (!m_data->isType(Node::NODE_UNDEFINED | Node::NODE_NAMESPACE)) { - MessageActivateTokens(m_data->getId()).dispatch(); + MessageActivateNode(m_data->getId(), m_data->getType(), m_data->getFullName()).dispatch(); } } diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index a0e33caa..8e62ae5b 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -2,13 +2,13 @@ #include "utility/logging/logging.h" #include "utility/messaging/MessageQueue.h" -#include "utility/messaging/type/MessageActivateTokens.h" +#include "utility/messaging/type/MessageActivateNode.h" #include "utility/messaging/type/MessageStatus.h" #include "utility/scheduling/TaskScheduler.h" #include "component/view/MainView.h" #include "component/view/ViewFactory.h" -#include "data/access/StorageAccessProxy.h" +#include "data/StorageCache.h" #include "settings/ApplicationSettings.h" std::shared_ptr Application::create(ViewFactory* viewFactory) @@ -17,9 +17,9 @@ std::shared_ptr Application::create(ViewFactory* viewFactory) std::shared_ptr ptr(new Application()); - ptr->m_storageAccessProxy = std::make_shared(); + ptr->m_storageCache = std::make_shared(); - ptr->m_componentManager = ComponentManager::create(viewFactory, ptr->m_storageAccessProxy.get()); + ptr->m_componentManager = ComponentManager::create(viewFactory, ptr->m_storageCache.get()); ptr->m_mainView = viewFactory->createMainView(); ptr->m_componentManager->setup(ptr->m_mainView.get()); @@ -51,7 +51,10 @@ void Application::loadProject(const std::string& projectSettingsFilePath) { MessageStatus("Loading Project: " + projectSettingsFilePath).dispatch(); - m_project = Project::create(m_storageAccessProxy.get()); + m_storageCache->clear(); + m_componentManager->refreshViews(); + + m_project = Project::create(m_storageCache.get()); m_project->loadProjectSettings(projectSettingsFilePath); m_project->parseCode(); @@ -61,7 +64,10 @@ void Application::loadSource(const std::string& sourceDirectoryPath) { MessageStatus("Loading Source: " + sourceDirectoryPath).dispatch(); - m_project = Project::create(m_storageAccessProxy.get()); + m_storageCache->clear(); + m_componentManager->refreshViews(); + + m_project = Project::create(m_storageCache.get()); m_project->clearProjectSettings(); m_project->setSourceDirectoryPath(sourceDirectoryPath); @@ -72,12 +78,15 @@ void Application::reloadProject() { MessageStatus("Refreshing Project").dispatch(); + m_storageCache->clear(); + m_componentManager->refreshViews(); + m_project->parseCode(); } void Application::saveProject(const std::string& projectSettingsFilePath) { - if(!m_project->saveProjectSettings(projectSettingsFilePath)) + if (!m_project->saveProjectSettings(projectSettingsFilePath)) { LOG_ERROR("No Project Settings File defined"); } @@ -92,16 +101,24 @@ void Application::handleMessage(MessageFinishedParsing* message) return; } - Id mainId = m_storageAccessProxy->getIdForNodeWithName("main"); + Id mainId = m_storageCache->getIdForNodeWithName("main"); - if (!mainId && m_storageAccessProxy->getNameForNodeWithId(1).size() > 0) + if (!mainId) { - mainId = 1; + std::vector ids = m_storageCache->getTokenIdsForQuery("'file'"); + if (ids.size()) + { + mainId = ids[0]; + } } if (mainId) { - MessageActivateTokens message(mainId); + MessageActivateNode message( + mainId, + m_storageCache->getNodeTypeForNodeWithId(mainId), + m_storageCache->getNameForNodeWithId(mainId) + ); message.isFromSystem = true; message.dispatch(); } diff --git a/src/lib/Application.h b/src/lib/Application.h index 7c493a8c..f71276c4 100644 --- a/src/lib/Application.h +++ b/src/lib/Application.h @@ -14,7 +14,7 @@ class ViewFactory; class MainView; -class StorageAccessProxy; +class StorageCache; class Application : public MessageListener @@ -44,7 +44,7 @@ private: virtual void handleMessage(MessageSaveProject* message); std::shared_ptr m_project; - std::shared_ptr m_storageAccessProxy; + std::shared_ptr m_storageCache; std::shared_ptr m_mainView; std::shared_ptr m_componentManager; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 66cc7f4e..d1abce5b 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -46,6 +46,8 @@ add_files( component/controller/CodeController.h component/controller/Controller.cpp component/controller/Controller.h + component/controller/FeatureController.cpp + component/controller/FeatureController.h component/controller/GraphController.cpp component/controller/GraphController.h component/controller/GraphLayouter.cpp @@ -204,6 +206,8 @@ add_files( data/Storage.cpp data/Storage.h + data/StorageCache.cpp + data/StorageCache.h settings/ApplicationSettings.cpp settings/ApplicationSettings.h @@ -247,7 +251,9 @@ add_files( utility/math/Vector4.h utility/math/VectorBase.h + utility/messaging/type/MessageActivateEdge.h utility/messaging/type/MessageActivateFile.h + utility/messaging/type/MessageActivateNode.h utility/messaging/type/MessageActivateTokenLocation.h utility/messaging/type/MessageActivateTokens.h utility/messaging/type/MessageAutoRefreshChanged.h diff --git a/src/lib/component/Component.cpp b/src/lib/component/Component.cpp index 089bd3ff..b5f580d8 100644 --- a/src/lib/component/Component.cpp +++ b/src/lib/component/Component.cpp @@ -7,12 +7,26 @@ Component::Component(std::shared_ptr view, std::shared_ptr con : m_controller(controller) , m_view(view) { - m_controller->setComponent(this); - m_view->setComponent(this); + if (m_controller) + { + m_controller->setComponent(this); + } + + if (m_view) + { + m_view->setComponent(this); + } } Component::~Component() { - m_controller->setComponent(NULL); - m_view->setComponent(NULL); + if (m_controller) + { + m_controller->setComponent(NULL); + } + + if (m_view) + { + m_view->setComponent(NULL); + } } diff --git a/src/lib/component/ComponentFactory.cpp b/src/lib/component/ComponentFactory.cpp index ab2cda98..0c70db34 100644 --- a/src/lib/component/ComponentFactory.cpp +++ b/src/lib/component/ComponentFactory.cpp @@ -2,6 +2,7 @@ #include "component/Component.h" #include "component/controller/CodeController.h" +#include "component/controller/FeatureController.h" #include "component/controller/GraphController.h" #include "component/controller/RefreshController.h" #include "component/controller/SearchController.h" @@ -42,6 +43,13 @@ std::shared_ptr ComponentFactory::createCodeComponent(ViewLayout* vie return std::make_shared(view, controller); } +std::shared_ptr ComponentFactory::createFeatureComponent() +{ + std::shared_ptr controller = std::make_shared(m_storageAccess); + + return std::make_shared(nullptr, controller); +} + std::shared_ptr ComponentFactory::createGraphComponent(ViewLayout* viewLayout) { std::shared_ptr view = m_viewFactory->createGraphView(viewLayout); diff --git a/src/lib/component/ComponentFactory.h b/src/lib/component/ComponentFactory.h index 544710a2..40beb2c0 100644 --- a/src/lib/component/ComponentFactory.h +++ b/src/lib/component/ComponentFactory.h @@ -19,6 +19,7 @@ public: ViewFactory* getViewFactory() const; std::shared_ptr createCodeComponent(ViewLayout* viewLayout); + std::shared_ptr createFeatureComponent(); std::shared_ptr createGraphComponent(ViewLayout* viewLayout); std::shared_ptr createRefreshComponent(ViewLayout* viewLayout); std::shared_ptr createSearchComponent(ViewLayout* viewLayout); diff --git a/src/lib/component/ComponentManager.cpp b/src/lib/component/ComponentManager.cpp index bd798aaf..29a5d84e 100644 --- a/src/lib/component/ComponentManager.cpp +++ b/src/lib/component/ComponentManager.cpp @@ -44,16 +44,24 @@ void ComponentManager::setup(ViewLayout* viewLayout) std::shared_ptr statusBarComponent = m_componentFactory->createStatusBarComponent(viewLayout); m_components.push_back(statusBarComponent); + + std::shared_ptr featureComponent = m_componentFactory->createFeatureComponent(); + m_components.push_back(featureComponent); +} + +void ComponentManager::refreshViews() +{ + for (std::shared_ptr component : m_components) + { + View* view = component->getView(); + + if (view) + { + view->refreshView(); + } + } } ComponentManager::ComponentManager() { } - -void ComponentManager::handleMessage(MessageRefresh* message) -{ - for (std::shared_ptr component : m_components) - { - component->getView()->refreshView(); - } -} diff --git a/src/lib/component/ComponentManager.h b/src/lib/component/ComponentManager.h index 18b26be0..c135da52 100644 --- a/src/lib/component/ComponentManager.h +++ b/src/lib/component/ComponentManager.h @@ -4,9 +4,6 @@ #include #include -#include "utility/messaging/MessageListener.h" -#include "utility/messaging/type/MessageRefresh.h" - #include "component/Component.h" #include "component/ComponentFactory.h" @@ -17,7 +14,6 @@ class ViewFactory; class ViewLayout; class ComponentManager - : public MessageListener { public: static std::shared_ptr create(ViewFactory* viewFactory, StorageAccess* graphAccess); @@ -26,12 +22,12 @@ public: void setup(ViewLayout* viewLayout); + void refreshViews(); + private: ComponentManager(); ComponentManager(const ComponentManager&); - void handleMessage(MessageRefresh* message); - std::shared_ptr m_componentFactory; std::vector> m_compositeViews; diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 49b09c6a..53ae1fa4 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -23,20 +23,6 @@ CodeController::~CodeController() const uint CodeController::s_lineRadius = 2; -void CodeController::handleMessage(MessageActivateFile* message) -{ - MessageActivateTokens(std::vector(1, m_storageAccess->getTokenIdForFileNode(message->filePath))).dispatch(); -} - -void CodeController::handleMessage(MessageActivateTokenLocation* message) -{ - if (message->locationId) - { - std::vector activeTokenIds = m_storageAccess->getActiveTokenIdsForLocationId(message->locationId); - MessageActivateTokens(activeTokenIds).dispatch(); - } -} - void CodeController::handleMessage(MessageActivateTokens* message) { std::vector activeTokenIds = message->tokenIds; diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index cea32e8a..b1594d84 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -5,8 +5,6 @@ #include #include "utility/messaging/MessageListener.h" -#include "utility/messaging/type/MessageActivateFile.h" -#include "utility/messaging/type/MessageActivateTokenLocation.h" #include "utility/messaging/type/MessageActivateTokens.h" #include "utility/messaging/type/MessageFinishedParsing.h" #include "utility/messaging/type/MessageFocusIn.h" @@ -24,8 +22,6 @@ class TokenLocationFile; class CodeController : public Controller - , public MessageListener - , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -39,8 +35,6 @@ public: private: static const uint s_lineRadius; - virtual void handleMessage(MessageActivateFile* message); - virtual void handleMessage(MessageActivateTokenLocation* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageFinishedParsing* message); virtual void handleMessage(MessageFocusIn* message); diff --git a/src/lib/component/controller/FeatureController.cpp b/src/lib/component/controller/FeatureController.cpp new file mode 100644 index 00000000..d59a8c73 --- /dev/null +++ b/src/lib/component/controller/FeatureController.cpp @@ -0,0 +1,79 @@ +#include "component/controller/FeatureController.h" + +#include "utility/messaging/type/MessageActivateTokens.h" + +#include "data/access/StorageAccess.h" + +FeatureController::FeatureController(StorageAccess* storageAccess) + : m_storageAccess(storageAccess) +{ +} + +FeatureController::~FeatureController() +{ +} + +void FeatureController::handleMessage(MessageActivateEdge* message) +{ + Id edgeId = message->tokenId; + + if (!message->isFresh()) + { + edgeId = m_storageAccess->getIdForEdgeWithName(message->name); + } + + if (!edgeId) + { + return; + } + + if (message->type == Edge::EDGE_AGGREGATION) + { + MessageActivateTokens(m_storageAccess->getTokenIdsForAggregationEdge(edgeId)).dispatch(); + return; + } + + MessageActivateTokens msg(std::vector(1, edgeId)); + msg.isEdge = true; + msg.dispatch(); +} + +void FeatureController::handleMessage(MessageActivateFile* message) +{ + MessageActivateTokens(std::vector(1, m_storageAccess->getTokenIdForFileNode(message->filePath))).dispatch(); +} + +void FeatureController::handleMessage(MessageActivateNode* message) +{ + Id nodeId = message->tokenId; + + if (!message->isFresh()) + { + nodeId = m_storageAccess->getIdForNodeWithName(message->name); + } + + if (nodeId) + { + MessageActivateTokens msg(nodeId); + msg.isFromSystem = message->isFromSystem; + msg.dispatch(); + } +} + +void FeatureController::handleMessage(MessageActivateTokenLocation* message) +{ + if (message->locationId) + { + Id nodeId = m_storageAccess->getActiveNodeIdForLocationId(message->locationId); + MessageActivateNode( + nodeId, + m_storageAccess->getNodeTypeForNodeWithId(nodeId), + m_storageAccess->getNameForNodeWithId(nodeId) + ).dispatch(); + } +} + +void FeatureController::handleMessage(MessageSearch* message) +{ + MessageActivateTokens(m_storageAccess->getTokenIdsForQuery(message->getQuery())).dispatch(); +} diff --git a/src/lib/component/controller/FeatureController.h b/src/lib/component/controller/FeatureController.h new file mode 100644 index 00000000..cf1c7db4 --- /dev/null +++ b/src/lib/component/controller/FeatureController.h @@ -0,0 +1,37 @@ +#ifndef FEATURE_CONTROLLER_H +#define FEATURE_CONTROLLER_H + +#include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/MessageActivateEdge.h" +#include "utility/messaging/type/MessageActivateFile.h" +#include "utility/messaging/type/MessageActivateNode.h" +#include "utility/messaging/type/MessageActivateTokenLocation.h" +#include "utility/messaging/type/MessageSearch.h" + +#include "component/controller/Controller.h" + +class StorageAccess; + +class FeatureController + : public Controller + , public MessageListener + , public MessageListener + , public MessageListener + , public MessageListener + , public MessageListener +{ +public: + FeatureController(StorageAccess* storageAccess); + ~FeatureController(); + +private: + virtual void handleMessage(MessageActivateEdge* message); + virtual void handleMessage(MessageActivateFile* message); + virtual void handleMessage(MessageActivateNode* message); + virtual void handleMessage(MessageActivateTokenLocation* message); + virtual void handleMessage(MessageSearch* message); + + StorageAccess* m_storageAccess; +}; + +#endif // FEATURE_CONTROLLER_H diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index de604a3e..0d63b77b 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -5,7 +5,6 @@ SearchController::SearchController(StorageAccess* storageAccess) : m_storageAccess(storageAccess) - , m_ignoreNextMessageActivateTokens(false) { } @@ -13,21 +12,37 @@ SearchController::~SearchController() { } -void SearchController::handleMessage(MessageActivateTokens* message) +void SearchController::handleMessage(MessageActivateEdge* message) { - if (!m_ignoreNextMessageActivateTokens && message->tokenIds.size()) - { - SearchMatch match; - match.fullName = m_storageAccess->getNameForNodeWithId(message->tokenIds[0]); - match.nodeType = m_storageAccess->getNodeTypeForNodeWithId(message->tokenIds[0]); - match.tokenIds.insert(message->tokenIds[0]); - match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; + SearchMatch match; + match.fullName = message->name; + match.nodeType = Node::NODE_CLASS; + match.tokenIds.insert(message->tokenId); + match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; + getView()->setMatches(std::deque(1, match)); +} - getView()->setMatch(match); - } +void SearchController::handleMessage(MessageActivateFile* message) +{ + SearchMatch match; + match.fullName = message->filePath.fileName(); + match.nodeType = Node::NODE_FILE; + match.tokenIds.insert(m_storageAccess->getTokenIdForFileNode(message->filePath)); + match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; - m_ignoreNextMessageActivateTokens = false; + getView()->setMatches(std::deque(1, match)); +} + +void SearchController::handleMessage(MessageActivateNode* message) +{ + SearchMatch match; + match.fullName = message->name; + match.nodeType = message->type; + match.tokenIds.insert(message->tokenId); + match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN; + + getView()->setMatches(std::deque(1, match)); } void SearchController::handleMessage(MessageFind* message) @@ -37,28 +52,12 @@ void SearchController::handleMessage(MessageFind* message) void SearchController::handleMessage(MessageFinishedParsing* message) { - getView()->setText(""); + getView()->setMatches(std::deque()); } void SearchController::handleMessage(MessageSearch* message) { - const std::string& query = message->query; - - LOG_INFO("search string: \"" + query + "\""); - - m_ignoreNextMessageActivateTokens = true; - - std::vector ids = m_storageAccess->getTokenIdsForQuery(query); - if (!ids.size()) - { - Id id = m_storageAccess->getIdForNodeWithName(query); - if (id > 0) - { - ids.push_back(id); - } - } - - MessageActivateTokens(ids).dispatch(); + getView()->setMatches(message->getMatches()); } void SearchController::handleMessage(MessageSearchAutocomplete* message) diff --git a/src/lib/component/controller/SearchController.h b/src/lib/component/controller/SearchController.h index 0558ec72..5c179a05 100644 --- a/src/lib/component/controller/SearchController.h +++ b/src/lib/component/controller/SearchController.h @@ -5,7 +5,9 @@ #include "component/controller/Controller.h" #include "utility/messaging/MessageListener.h" -#include "utility/messaging/type/MessageActivateTokens.h" +#include "utility/messaging/type/MessageActivateEdge.h" +#include "utility/messaging/type/MessageActivateFile.h" +#include "utility/messaging/type/MessageActivateNode.h" #include "utility/messaging/type/MessageFind.h" #include "utility/messaging/type/MessageFinishedParsing.h" #include "utility/messaging/type/MessageSearch.h" @@ -16,7 +18,9 @@ class SearchView; class SearchController : public Controller - , public MessageListener + , public MessageListener + , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -27,7 +31,9 @@ public: ~SearchController(); private: - virtual void handleMessage(MessageActivateTokens* message); + virtual void handleMessage(MessageActivateEdge* message); + virtual void handleMessage(MessageActivateFile* message); + virtual void handleMessage(MessageActivateNode* message); virtual void handleMessage(MessageFind* message); virtual void handleMessage(MessageFinishedParsing* message); virtual void handleMessage(MessageSearch* message); @@ -36,8 +42,6 @@ private: SearchView* getView(); StorageAccess* m_storageAccess; - - bool m_ignoreNextMessageActivateTokens; }; #endif // SEARCH_CONTROLLER_H diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 2a9c708b..fd6bb627 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -1,8 +1,9 @@ #include "component/controller/UndoRedoController.h" -#include "component/view/UndoRedoView.h" #include "utility/logging/logging.h" +#include "component/view/UndoRedoView.h" + UndoRedoController::UndoRedoController() : m_lastCommand(nullptr) { @@ -17,108 +18,153 @@ UndoRedoView* UndoRedoController::getView() return Controller::getView(); } -void UndoRedoController::handleMessage(MessageActivateTokens* message) +void UndoRedoController::handleMessage(MessageActivateEdge* message) { - if(m_lastCommand && m_lastCommand->getType() == "MessageActivateTokens") - { - if(static_cast(m_lastCommand.get())->tokenIds == message->tokenIds) - { - return; - } - } - std::shared_ptr m = std::shared_ptr(new MessageActivateTokens(*message)); - std::shared_ptr msg = m; - processMessage(msg); + if (m_lastCommand && m_lastCommand->getType() == message->getType() && + static_cast(m_lastCommand.get())->name == message->name) + { + return; + } + + processMessage(std::make_shared(*message)); +} + +void UndoRedoController::handleMessage(MessageActivateFile* message) +{ + if (m_lastCommand && m_lastCommand->getType() == message->getType() && + static_cast(m_lastCommand.get())->filePath == message->filePath) + { + return; + } + + processMessage(std::make_shared(*message)); +} + +void UndoRedoController::handleMessage(MessageActivateNode* message) +{ + if (m_lastCommand && m_lastCommand->getType() == message->getType() && + static_cast(m_lastCommand.get())->name == message->name) + { + return; + } + + processMessage(std::make_shared(*message)); } void UndoRedoController::handleMessage(MessageGraphNodeExpand* message) { - /*MessageGraphNodeExpand* m = new MessageGraphNodeExpand(message->tokenId,message->access); - m->UndoRedoType = message->UndoRedoType; - processMessage(m);*/ } void UndoRedoController::handleMessage(MessageGraphNodeMove* message) { - /*MessageGraphNodeMove* m = new MessageGraphNodeMove(message->tokenId,message->position); - m->UndoRedoType = message->UndoRedoType; - processMessage(m, true);*/ +} + +void UndoRedoController::handleMessage(MessageLoadProject* message) +{ + clear(); +} + +void UndoRedoController::handleMessage(MessageLoadSource* message) +{ + clear(); } void UndoRedoController::handleMessage(MessageRedo* message) { - if(!m_redo.empty()) - { - std::shared_ptr m = m_redo.back(); - m_redo.pop_back(); - m->UndoRedoType = MessageBase::UndoType_Redo; - m->dispatch(); - } + if (!m_redo.empty()) + { + std::shared_ptr m = m_redo.back(); + m_redo.pop_back(); + m->undoRedoType = MessageBase::UndoType_Redo; + m->dispatch(); + } +} + +void UndoRedoController::handleMessage(MessageSearch* message) +{ + if (m_lastCommand && m_lastCommand->getType() == message->getType() && + static_cast(m_lastCommand.get())->getQuery() == message->getQuery()) + { + return; + } + + processMessage(std::make_shared(*message)); } void UndoRedoController::handleMessage(MessageUndo* message) { - if(!m_undo.empty()) - { - std::shared_ptr m = m_undo.back(); - m_undo.pop_back(); - m->UndoRedoType = MessageBase::UndoType_Undo; - m->dispatch(); - } + if (!m_undo.empty()) + { + std::shared_ptr m = m_undo.back(); + m_undo.pop_back(); + m->undoRedoType = MessageBase::UndoType_Undo; + m->dispatch(); + } } void UndoRedoController::processMessage(std::shared_ptr message) { - switch(message->UndoRedoType) - { - case MessageBase::UndoType_Normal: - processNormalMessage(message);; - break; - case MessageBase::UndoType_Redo: - processRedoMessage(message); - break; - case MessageBase::UndoType_Undo: - processUndoMessage(message); - break; - } + switch (message->undoRedoType) + { + case MessageBase::UndoType_Normal: + processNormalMessage(message);; + break; + case MessageBase::UndoType_Redo: + processRedoMessage(message); + break; + case MessageBase::UndoType_Undo: + processUndoMessage(message); + break; + } } - void UndoRedoController::processNormalMessage(std::shared_ptr message) { - if(m_lastCommand != nullptr) - { - m_undo.push_back(m_lastCommand); - getView()->setUndoButtonEnabled(true); - } - m_lastCommand = message; - while(!m_redo.empty()) - { - std::shared_ptr m = m_redo.back(); - m_redo.pop_back(); - } - getView()->setRedoButtonEnabled(false); + if (m_lastCommand) + { + m_undo.push_back(m_lastCommand); + getView()->setUndoButtonEnabled(true); + } + + m_lastCommand = message; + + m_redo.clear(); + getView()->setRedoButtonEnabled(false); } void UndoRedoController::processRedoMessage(std::shared_ptr message) { - m_undo.push_back(m_lastCommand); - getView()->setUndoButtonEnabled(true); - m_lastCommand = message; - if(m_redo.empty()) - { - getView()->setRedoButtonEnabled(false); - } + m_undo.push_back(m_lastCommand); + m_lastCommand = message; + + getView()->setUndoButtonEnabled(true); + + if (m_redo.empty()) + { + getView()->setRedoButtonEnabled(false); + } } void UndoRedoController::processUndoMessage(std::shared_ptr message) { - m_redo.push_back(m_lastCommand); - getView()->setRedoButtonEnabled(true); - m_lastCommand = message; - if(m_undo.empty()) - { - getView()->setUndoButtonEnabled(false); - } + m_redo.push_back(m_lastCommand); + m_lastCommand = message; + + getView()->setRedoButtonEnabled(true); + + if (m_undo.empty()) + { + getView()->setUndoButtonEnabled(false); + } } +void UndoRedoController::clear() +{ + m_lastCommand = nullptr; + + m_undo.clear(); + m_redo.clear(); + + getView()->setUndoButtonEnabled(false); + getView()->setRedoButtonEnabled(false); +} diff --git a/src/lib/component/controller/UndoRedoController.h b/src/lib/component/controller/UndoRedoController.h index daf1904e..66f9b645 100644 --- a/src/lib/component/controller/UndoRedoController.h +++ b/src/lib/component/controller/UndoRedoController.h @@ -2,46 +2,53 @@ #define UNDO_REDO_CONTROLLER_H #include -#include -#include -#include - -#include "component/controller/Controller.h" #include "utility/messaging/MessageBase.h" #include "utility/messaging/MessageListener.h" -#include "utility/messaging/type/MessageActivateTokens.h" +#include "utility/messaging/type/MessageActivateEdge.h" +#include "utility/messaging/type/MessageActivateFile.h" +#include "utility/messaging/type/MessageActivateNode.h" #include "utility/messaging/type/MessageGraphNodeExpand.h" #include "utility/messaging/type/MessageGraphNodeMove.h" +#include "utility/messaging/type/MessageLoadProject.h" +#include "utility/messaging/type/MessageLoadSource.h" #include "utility/messaging/type/MessageRedo.h" +#include "utility/messaging/type/MessageSearch.h" #include "utility/messaging/type/MessageUndo.h" +#include "component/controller/Controller.h" + class UndoRedoView; class UndoRedoController : public Controller - , public MessageListener + , public MessageListener + , public MessageListener + , public MessageListener , public MessageListener , public MessageListener + , public MessageListener + , public MessageListener , public MessageListener + , public MessageListener , public MessageListener { public: - UndoRedoController(void); - virtual ~UndoRedoController(void); - UndoRedoView* getView(); -private: - enum UndoRedoType - { - UndoRedoType_Normal, - UndoRedoType_Undo, - UndoRedoType_Redo - }; + UndoRedoController(); + virtual ~UndoRedoController(); - virtual void handleMessage(MessageActivateTokens* message); + UndoRedoView* getView(); + +private: + virtual void handleMessage(MessageActivateEdge* message); + virtual void handleMessage(MessageActivateFile* message); + virtual void handleMessage(MessageActivateNode* message); virtual void handleMessage(MessageGraphNodeExpand* message); virtual void handleMessage(MessageGraphNodeMove* message); + virtual void handleMessage(MessageLoadProject* message); + virtual void handleMessage(MessageLoadSource* message); virtual void handleMessage(MessageRedo* message); + virtual void handleMessage(MessageSearch* message); virtual void handleMessage(MessageUndo* message); void processMessage(std::shared_ptr message); @@ -49,6 +56,8 @@ private: void processRedoMessage(std::shared_ptr message); void processUndoMessage(std::shared_ptr message); + void clear(); + std::shared_ptr m_lastCommand; std::deque> m_undo; diff --git a/src/lib/component/view/SearchView.h b/src/lib/component/view/SearchView.h index 26cd9922..3d6801d6 100644 --- a/src/lib/component/view/SearchView.h +++ b/src/lib/component/view/SearchView.h @@ -14,8 +14,7 @@ public: virtual std::string getName() const; - virtual void setText(const std::string& s) = 0; - virtual void setMatch(const SearchMatch& m) = 0; + virtual void setMatches(const std::deque& matches) = 0; virtual void setFocus() = 0; virtual void setAutocompletionList(const std::vector& autocompletionList) = 0; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index ef331d99..aed4080b 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -7,6 +7,7 @@ #include "utility/file/FileSystem.h" #include "data/graph/filter/GraphFilterConductor.h" +#include "data/graph/token_component/TokenComponentAggregation.h" #include "data/graph/token_component/TokenComponentConst.h" #include "data/graph/token_component/TokenComponentName.h" #include "data/graph/token_component/TokenComponentStatic.h" @@ -683,6 +684,42 @@ Id Storage::getIdForNodeWithName(const std::string& fullName) const return 0; } +Id Storage::getIdForEdgeWithName(const std::string& name) const +{ + Edge::EdgeType type; + std::string fromName; + std::string toName; + + Edge::splitName(name, &type, &fromName, &toName); + + Id fromId = getIdForNodeWithName(fromName); + Node* from = m_graph.getNodeById(fromId); + + if (from) + { + Edge* edge = from->findEdgeOfType( + type, + [&name](Edge* e) + { + return (e->getName() == name); + } + ); + + if (edge) + { + if (!edge->isType(type)) + { + LOG_ERROR_STREAM(<< "Edge: " << name << " is not of type: " << Edge::getTypeString(type)); + return 0; + } + + return edge->getId(); + } + } + + return 0; +} + std::string Storage::getNameForNodeWithId(Id id) const { Token* token = m_graph.getTokenById(id); @@ -890,34 +927,28 @@ std::vector Storage::getActiveTokenIdsForId(Id tokenId, Id* declarationId) c return ret; } -std::vector Storage::getActiveTokenIdsForLocationId(Id locationId) const +Id Storage::getActiveNodeIdForLocationId(Id locationId) const { - std::vector ret; - TokenLocation* location = m_locationCollection.findTokenLocationById(locationId); if (!location) { - return ret; + return 0; } Token* token = m_graph.getTokenById(location->getTokenId()); if (!token) { - return ret; + return 0; } if (token->isNode()) { - Node* node = dynamic_cast(token); - ret.push_back(node->getId()); + return dynamic_cast(token)->getId(); } else { - Edge* edge = dynamic_cast(token); - ret.push_back(edge->getTo()->getId()); + return dynamic_cast(token)->getTo()->getId(); } - - return ret; } std::vector Storage::getTokenIdsForQuery(std::string query) const @@ -944,6 +975,20 @@ Id Storage::getTokenIdForFileNode(const FilePath& filePath) const return 0; } +std::vector Storage::getTokenIdsForAggregationEdge(Id aggregationId) const +{ + Edge* edge = m_graph.getEdgeById(aggregationId); + std::vector ids; + + if (edge->isType(Edge::EDGE_AGGREGATION)) + { + std::set i = edge->getComponent()->getAggregationIds(); + ids.insert(ids.end(), i.begin(), i.end()); + } + + return ids; +} + TokenLocationCollection Storage::getTokenLocationsForTokenIds(const std::vector& tokenIds) const { TokenLocationCollection ret; diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 05c7fb66..d4fad591 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -109,6 +109,8 @@ public: // StorageAccess implementation virtual Id getIdForNodeWithName(const std::string& fullName) const; + virtual Id getIdForEdgeWithName(const std::string& name) const; + virtual std::string getNameForNodeWithId(Id id) const; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const; virtual std::vector getAutocompletionMatches( @@ -117,10 +119,11 @@ public: virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const; virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const; - virtual std::vector getActiveTokenIdsForLocationId(Id locationId) const; + virtual Id getActiveNodeIdForLocationId(Id locationId) const; virtual std::vector getTokenIdsForQuery(std::string query) const; virtual Id getTokenIdForFileNode(const FilePath& filePath) const; + virtual std::vector getTokenIdsForAggregationEdge(Id aggregationId) const; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const; virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const; diff --git a/src/lib/data/StorageCache.cpp b/src/lib/data/StorageCache.cpp new file mode 100644 index 00000000..d01434c1 --- /dev/null +++ b/src/lib/data/StorageCache.cpp @@ -0,0 +1,22 @@ +#include "data/StorageCache.h" + +void StorageCache::clear() +{ + m_queryToTokenIds.clear(); +} + +std::vector StorageCache::getTokenIdsForQuery(std::string query) const +{ + std::map>::const_iterator it = m_queryToTokenIds.find(query); + + if (it != m_queryToTokenIds.end()) + { + return it->second; + } + + std::vector ids = StorageAccessProxy::getTokenIdsForQuery(query); + + m_queryToTokenIds.emplace(query, ids); + + return ids; +} diff --git a/src/lib/data/StorageCache.h b/src/lib/data/StorageCache.h new file mode 100644 index 00000000..ff8d5b89 --- /dev/null +++ b/src/lib/data/StorageCache.h @@ -0,0 +1,20 @@ +#ifndef STORAGE_CACHE_H +#define STORAGE_CACHE_H + +#include + +#include "data/access/StorageAccessProxy.h" + +class StorageCache + : public StorageAccessProxy +{ +public: + void clear(); + + virtual std::vector getTokenIdsForQuery(std::string query) const; + +private: + mutable std::map> m_queryToTokenIds; +}; + +#endif // STORAGE_CACHE_H diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 8c5095c3..b5020338 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -22,6 +22,8 @@ public: virtual ~StorageAccess(); virtual Id getIdForNodeWithName(const std::string& name) const = 0; + virtual Id getIdForEdgeWithName(const std::string& name) const = 0; + virtual std::string getNameForNodeWithId(Id id) const = 0; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0; virtual std::vector getAutocompletionMatches( @@ -30,10 +32,11 @@ public: virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const = 0; virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const = 0; - virtual std::vector getActiveTokenIdsForLocationId(Id locationId) const = 0; + virtual Id getActiveNodeIdForLocationId(Id locationId) const = 0; virtual std::vector getTokenIdsForQuery(std::string query) const = 0; virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0; + virtual std::vector getTokenIdsForAggregationEdge(Id aggregationId) const = 0; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const = 0; virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index d240d9ef..28d175e7 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -41,6 +41,16 @@ Id StorageAccessProxy::getIdForNodeWithName(const std::string& name) const return 0; } +Id StorageAccessProxy::getIdForEdgeWithName(const std::string& name) const +{ + if (hasSubject()) + { + return m_subject->getIdForEdgeWithName(name); + } + + return 0; +} + Node::NodeType StorageAccessProxy::getNodeTypeForNodeWithId(Id id) const { if(hasSubject()) @@ -92,14 +102,14 @@ std::vector StorageAccessProxy::getActiveTokenIdsForId(Id tokenId, Id* delca return std::vector(); } -std::vector StorageAccessProxy::getActiveTokenIdsForLocationId(Id locationId) const +Id StorageAccessProxy::getActiveNodeIdForLocationId(Id locationId) const { if (hasSubject()) { - return m_subject->getActiveTokenIdsForLocationId(locationId); + return m_subject->getActiveNodeIdForLocationId(locationId); } - return std::vector(); + return 0; } std::vector StorageAccessProxy::getTokenIdsForQuery(std::string query) const @@ -122,6 +132,16 @@ Id StorageAccessProxy::getTokenIdForFileNode(const FilePath& filePath) const return 0; } +std::vector StorageAccessProxy::getTokenIdsForAggregationEdge(Id aggregationId) const +{ + if (hasSubject()) + { + return m_subject->getTokenIdsForAggregationEdge(aggregationId); + } + + return std::vector(); +} + TokenLocationCollection StorageAccessProxy::getTokenLocationsForTokenIds(const std::vector& tokenIds) const { if (hasSubject()) diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index c5d0074a..ffea60eb 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -14,6 +14,8 @@ public: // StorageAccess implementation virtual Id getIdForNodeWithName(const std::string& name) const; + virtual Id getIdForEdgeWithName(const std::string& name) const; + virtual std::string getNameForNodeWithId(Id id) const; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const; virtual std::vector getAutocompletionMatches( @@ -22,10 +24,11 @@ public: virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const; virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const; - virtual std::vector getActiveTokenIdsForLocationId(Id locationId) const; + virtual Id getActiveNodeIdForLocationId(Id locationId) const; virtual std::vector getTokenIdsForQuery(std::string query) const; virtual Id getTokenIdForFileNode(const FilePath& filePath) const; + virtual std::vector getTokenIdsForAggregationEdge(Id aggregationId) const; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const; virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const; diff --git a/src/lib/data/graph/Edge.cpp b/src/lib/data/graph/Edge.cpp index 5c0b531d..90328724 100644 --- a/src/lib/data/graph/Edge.cpp +++ b/src/lib/data/graph/Edge.cpp @@ -6,6 +6,7 @@ #include "data/graph/token_component/TokenComponentAggregation.h" #include "data/graph/token_component/TokenComponentAccess.h" #include "utility/logging/logging.h" +#include "utility/utilityString.h" Edge::Edge(EdgeType type, Node* from, Node* to) : m_type(type) @@ -67,6 +68,24 @@ std::string Edge::getName() const return getTypeString() + ":" + getFrom()->getFullName() + "->" + getTo()->getFullName(); } +void Edge::splitName(const std::string& name, EdgeType* type, std::string* fromName, std::string* toName) +{ + EdgeTypeMask mask = 1; + std::string typeStr = utility::substrBefore(name, ':'); + + while (typeStr != getTypeString(static_cast(mask))) + { + mask = mask << 1; + } + + *type = static_cast(mask); + + std::string names = utility::substrAfter(name, ':'); + + *fromName = utility::substrBefore(names, '-'); + *toName = utility::substrAfter(utility::substrAfter(names, '-'), '>'); +} + bool Edge::isNode() const { return false; @@ -110,7 +129,7 @@ void Edge::addComponentAccess(std::shared_ptr component) } } -std::string Edge::getTypeString(EdgeType type) const +std::string Edge::getTypeString(EdgeType type) { switch (type) { diff --git a/src/lib/data/graph/Edge.h b/src/lib/data/graph/Edge.h index 6eab0493..cfb9a3bd 100644 --- a/src/lib/data/graph/Edge.h +++ b/src/lib/data/graph/Edge.h @@ -48,6 +48,7 @@ public: Node* getTo() const; std::string getName() const; + static void splitName(const std::string& name, EdgeType* type, std::string* fromName, std::string* toName); // Token implementation virtual bool isNode() const; @@ -58,7 +59,7 @@ public: void addComponentAccess(std::shared_ptr component); // Logging. - std::string getTypeString(EdgeType type) const; + static std::string getTypeString(EdgeType type); virtual std::string getTypeString() const; std::string getAsString() const; diff --git a/src/lib/data/graph/filter/GraphFilterImplementations.h b/src/lib/data/graph/filter/GraphFilterImplementations.h index b10c6742..e5d3b7cb 100644 --- a/src/lib/data/graph/filter/GraphFilterImplementations.h +++ b/src/lib/data/graph/filter/GraphFilterImplementations.h @@ -257,15 +257,27 @@ public: virtual void apply(const FilterableGraph* in, FilterableGraph* out) { - if (m_tokenIds.size()) + std::vector nodes; + + for (Id tokenId : m_tokenIds) { - for (Id tokenId : m_tokenIds) + Node* node = in->getNodeById(tokenId); + if (node) { - Node* node = in->getNodeById(tokenId); - if (node) - { - out->addNode(node); - } + nodes.push_back(node); + } + else + { + nodes.clear(); + break; + } + } + + if (nodes.size()) + { + for (Node* node : nodes) + { + out->addNode(node); } } else diff --git a/src/lib/data/search/SearchMatch.cpp b/src/lib/data/search/SearchMatch.cpp index be9d6ace..fa9a1c93 100644 --- a/src/lib/data/search/SearchMatch.cpp +++ b/src/lib/data/search/SearchMatch.cpp @@ -129,7 +129,11 @@ std::deque SearchMatch::searchMatchDequeToStringDeque(const std::de stringDeque.push_back(match.encodeForQuery()); } return stringDeque; +} +std::string SearchMatch::searchMatchDequeToString(const std::deque& searchMatchDeque) +{ + return utility::join(searchMatchDequeToStringDeque(searchMatchDeque), ""); } std::string SearchMatch::getNodeTypeAsString() const diff --git a/src/lib/data/search/SearchMatch.h b/src/lib/data/search/SearchMatch.h index a5ba0138..1c696cef 100644 --- a/src/lib/data/search/SearchMatch.h +++ b/src/lib/data/search/SearchMatch.h @@ -16,6 +16,7 @@ struct SearchMatch static void log(const std::vector& matches, const std::string& query); static std::deque stringDequeToSearchMatchDeque(const std::deque& deque); static std::deque searchMatchDequeToStringDeque(const std::deque& deque); + static std::string searchMatchDequeToString(const std::deque& deque); SearchMatch(); SearchMatch(const std::string& query); diff --git a/src/lib/utility/messaging/MessageBase.h b/src/lib/utility/messaging/MessageBase.h index 8cdb5a92..bf40c5d7 100644 --- a/src/lib/utility/messaging/MessageBase.h +++ b/src/lib/utility/messaging/MessageBase.h @@ -14,7 +14,7 @@ public: }; MessageBase() - : UndoRedoType(UndoType_Normal) + : undoRedoType(UndoType_Normal) , m_sendAsTask(true) { } @@ -36,7 +36,12 @@ public: m_sendAsTask = sendAsTask; } - UndoType UndoRedoType; + bool isFresh() const + { + return (undoRedoType == UndoType_Normal); + } + + UndoType undoRedoType; private: bool m_sendAsTask; diff --git a/src/lib/utility/messaging/type/MessageActivateEdge.h b/src/lib/utility/messaging/type/MessageActivateEdge.h new file mode 100644 index 00000000..e293e6ad --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateEdge.h @@ -0,0 +1,30 @@ +#ifndef MESSAGE_ACTIVATE_EDGE_H +#define MESSAGE_ACTIVATE_EDGE_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +#include "data/graph/Edge.h" + +class MessageActivateEdge + : public Message +{ +public: + MessageActivateEdge(Id tokenId, Edge::EdgeType type, const std::string& name) + : tokenId(tokenId) + , type(type) + , name(name) + { + } + + static const std::string getStaticType() + { + return "MessageActivateEdge"; + } + + const Id tokenId; + const Edge::EdgeType type; + const std::string name; +}; + +#endif // MESSAGE_ACTIVATE_EDGE_H diff --git a/src/lib/utility/messaging/type/MessageActivateNode.h b/src/lib/utility/messaging/type/MessageActivateNode.h new file mode 100644 index 00000000..a3de8cc7 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateNode.h @@ -0,0 +1,33 @@ +#ifndef MESSAGE_ACTIVATE_NODE_H +#define MESSAGE_ACTIVATE_NODE_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +#include "data/graph/Node.h" + +class MessageActivateNode + : public Message +{ +public: + MessageActivateNode(Id tokenId, Node::NodeType type, const std::string& name) + : tokenId(tokenId) + , type(type) + , name(name) + , isFromSystem(false) + { + } + + static const std::string getStaticType() + { + return "MessageActivateNode"; + } + + const Id tokenId; + const Node::NodeType type; + const std::string name; + + bool isFromSystem; +}; + +#endif // MESSAGE_ACTIVATE_NODE_H diff --git a/src/lib/utility/messaging/type/MessageActivateTokens.h b/src/lib/utility/messaging/type/MessageActivateTokens.h index 70b41f81..ad560f6f 100644 --- a/src/lib/utility/messaging/type/MessageActivateTokens.h +++ b/src/lib/utility/messaging/type/MessageActivateTokens.h @@ -29,7 +29,6 @@ public: const std::vector tokenIds; bool isEdge; - bool isBundle; bool isFromSystem; }; diff --git a/src/lib/utility/messaging/type/MessageSearch.h b/src/lib/utility/messaging/type/MessageSearch.h index 1c1893bb..e0959d54 100644 --- a/src/lib/utility/messaging/type/MessageSearch.h +++ b/src/lib/utility/messaging/type/MessageSearch.h @@ -1,14 +1,24 @@ #ifndef MESSAGE_SEARCH_H #define MESSAGE_SEARCH_H -#include "utility/messaging/Message.h" -#include "utility/types.h" +#include -class MessageSearch: public Message +#include "utility/messaging/Message.h" +#include "utility/utilityString.h" + +#include "data/search/SearchMatch.h" + +class MessageSearch + : public Message { public: MessageSearch(const std::string& query) - : query(query) + : m_query(query) + { + } + + MessageSearch(const std::deque& matches) + : m_matches(matches) { } @@ -17,7 +27,24 @@ public: return "MessageSearch"; } - const std::string query; + std::string getQuery() const + { + if (m_query.size()) + { + return m_query; + } + + return utility::join(SearchMatch::searchMatchDequeToStringDeque(m_matches), ""); + } + + const std::deque& getMatches() const + { + return m_matches; + } + +private: + const std::string m_query; + const std::deque m_matches; }; #endif // MESSAGE_SEARCH_H diff --git a/src/lib/utility/utilityString.cpp b/src/lib/utility/utilityString.cpp index fbc7d2be..7477bada 100644 --- a/src/lib/utility/utilityString.cpp +++ b/src/lib/utility/utilityString.cpp @@ -100,6 +100,16 @@ namespace utility return c; } + std::string substrBefore(const std::string& str, char delimiter) + { + size_t pos = str.find(delimiter); + if (pos != std::string::npos) + { + return str.substr(0, pos); + } + return str; + } + std::string substrAfter(const std::string& str, char delimiter) { size_t pos = str.find(delimiter); diff --git a/src/lib/utility/utilityString.h b/src/lib/utility/utilityString.h index bb459ad9..da83083e 100644 --- a/src/lib/utility/utilityString.h +++ b/src/lib/utility/utilityString.h @@ -29,6 +29,7 @@ namespace utility std::deque tokenize(const std::deque& list, char delimiter); std::deque tokenize(const std::deque& list, const std::string& delimiter); + std::string substrBefore(const std::string& str, char delimiter); std::string substrAfter(const std::string& str, char delimiter); bool isPrefix(const std::string& prefix, const std::string& text); diff --git a/src/test/UtilityStringTestSuite.h b/src/test/UtilityStringTestSuite.h index 94f66c3b..1dd468b2 100644 --- a/src/test/UtilityStringTestSuite.h +++ b/src/test/UtilityStringTestSuite.h @@ -156,6 +156,31 @@ public: TS_ASSERT_EQUALS(result.at(6), "D"); } + void test_substr_before_with_single_delimiter_occurence() + { + TS_ASSERT_EQUALS(utility::substrBefore("foo bar", ' '), "foo"); + } + + void test_substr_before_with_multiple_delimiter_occurences() + { + TS_ASSERT_EQUALS(utility::substrBefore("foo bar foo", ' '), "foo"); + } + + void test_substr_before_with_no_delimiter_occurence() + { + TS_ASSERT_EQUALS(utility::substrBefore("foobar", ' '), "foobar"); + } + + void test_substr_before_with_delimiter_at_start() + { + TS_ASSERT_EQUALS(utility::substrBefore(" foobar", ' '), ""); + } + + void test_substr_before_with_delimiter_at_end() + { + TS_ASSERT_EQUALS(utility::substrBefore("foobar ", ' '), "foobar"); + } + void test_substr_after_with_single_delimiter_occurence() { TS_ASSERT_EQUALS(utility::substrAfter("foo bar", ' '), "bar");