diff --git a/src/app/qt/element/QtCodeArea.cpp b/src/app/qt/element/QtCodeArea.cpp index 7896ff18..1ac607ef 100644 --- a/src/app/qt/element/QtCodeArea.cpp +++ b/src/app/qt/element/QtCodeArea.cpp @@ -6,7 +6,7 @@ #include #include -#include "utility/messaging/type/MessageActivateTokenLocation.h" +#include "utility/messaging/type/MessageActivateTokenLocations.h" #include "utility/messaging/type/MessageShowFile.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" @@ -234,11 +234,11 @@ void QtCodeArea::mouseReleaseEvent(QMouseEvent* event) if (event->button() == Qt::LeftButton) { QTextCursor cursor = this->cursorForPosition(event->pos()); - const Annotation* annotation = findAnnotationForPosition(cursor.position()); + std::vector locationIds = findLocationIdsForPosition(cursor.position()); - if (annotation && !annotation->isScope) + if (locationIds.size()) { - MessageActivateTokenLocation(annotation->locationId).dispatch(); + MessageActivateTokenLocations(locationIds).dispatch(); } } } @@ -254,6 +254,8 @@ void QtCodeArea::mouseDoubleClickEvent(QMouseEvent* event) void QtCodeArea::mouseMoveEvent(QMouseEvent* event) { QTextCursor cursor = this->cursorForPosition(event->pos()); + + m_hoveredLocationIds = findLocationIdsForPosition(cursor.position()); const Annotation* annotation = findAnnotationForPosition(cursor.position()); if (annotation && annotation->isScope) @@ -268,12 +270,15 @@ void QtCodeArea::mouseMoveEvent(QMouseEvent* event) setHoveredAnnotation(annotation); const std::vector& errorMessages = m_fileWidget->getErrorMessages(); - if (annotation && errorMessages.size() > annotation->tokenId) { QToolTip::showText(event->globalPos(), QString::fromStdString(errorMessages[annotation->tokenId])); } } + else if (m_hoveredLocationIds.size()) + { + updateContent(); + } } void QtCodeArea::updateLineNumberAreaWidth(int /* newBlockCount */) @@ -339,6 +344,21 @@ const QtCodeArea::Annotation* QtCodeArea::findAnnotationForPosition(int pos) con return annotationPtr; } +std::vector QtCodeArea::findLocationIdsForPosition(int pos) const +{ + std::vector locationIds; + + for (const Annotation& annotation : m_annotations) + { + if (!annotation.isScope && pos >= annotation.start && pos <= annotation.end) + { + locationIds.push_back(annotation.locationId); + } + } + + return locationIds; +} + void QtCodeArea::createAnnotations(std::shared_ptr locationFile) { locationFile->forEachStartTokenLocation( @@ -390,7 +410,8 @@ void QtCodeArea::createAnnotations(std::shared_ptr locationFi void QtCodeArea::annotateText() { Id focusedTokenId = m_fileWidget->getFocusedTokenId(); - const std::vector& ids = m_fileWidget->getActiveTokenIds(); + const std::vector& activeIds = m_fileWidget->getActiveTokenIds(); + const std::vector& hoverIds = m_hoveredLocationIds; const std::vector& errorMessages = m_fileWidget->getErrorMessages(); std::vector scopeAnnotations; @@ -407,11 +428,12 @@ void QtCodeArea::annotateText() for (const Annotation& annotation: m_annotations) { - bool isActive = std::find(ids.begin(), ids.end(), annotation.tokenId) != ids.end(); + bool isActive = std::find(activeIds.begin(), activeIds.end(), annotation.tokenId) != activeIds.end(); + bool isHovered = std::find(hoverIds.begin(), hoverIds.end(), annotation.locationId) != hoverIds.end(); bool isFocused = (annotation.tokenId == focusedTokenId); QColor color; - if (&annotation == m_hoveredAnnotation && errorMessages.size()) + if (isHovered && errorMessages.size()) { color = activeErrorColor; } @@ -419,7 +441,7 @@ void QtCodeArea::annotateText() { color = errorColor; } - else if (isActive || isFocused) + else if (isActive || isFocused || isHovered) { color = activeLocationColor; } @@ -440,7 +462,7 @@ void QtCodeArea::annotateText() selection.cursor.setPosition(annotation.end, QTextCursor::KeepAnchor); scopeAnnotation.endLine = selection.cursor.blockNumber(); - if (annotation.isScope || (isActive && ids.size() == 1)) + if (annotation.isScope || (isActive && activeIds.size() == 1)) { if (isActive || isFocused) { @@ -453,7 +475,7 @@ void QtCodeArea::annotateText() } } - if (!annotation.isScope || (isActive && ids.size() == 1 && scopeAnnotation.startLine == scopeAnnotation.endLine)) + if (!annotation.isScope || (isActive && activeIds.size() == 1 && scopeAnnotation.startLine == scopeAnnotation.endLine)) { extraSelections.append(selection); } diff --git a/src/app/qt/element/QtCodeArea.h b/src/app/qt/element/QtCodeArea.h index 9791b81f..7607fbc0 100644 --- a/src/app/qt/element/QtCodeArea.h +++ b/src/app/qt/element/QtCodeArea.h @@ -102,6 +102,8 @@ private: }; const Annotation* findAnnotationForPosition(int pos) const; + std::vector findLocationIdsForPosition(int pos) const; + void createAnnotations(std::shared_ptr locationFile); void annotateText(); @@ -126,6 +128,7 @@ private: std::vector m_scopeAnnotations; const Annotation* m_hoveredAnnotation; + std::vector m_hoveredLocationIds; int m_digits; }; diff --git a/src/app/qt/view/QtMainView.cpp b/src/app/qt/view/QtMainView.cpp index 40180670..c7f263d9 100644 --- a/src/app/qt/view/QtMainView.cpp +++ b/src/app/qt/view/QtMainView.cpp @@ -62,3 +62,8 @@ void QtMainView::setStatusBar(QStatusBar* statusbar) { m_window->setStatusBar(statusbar); } + +void QtMainView::showStartScreen() +{ + m_window->showStartScreen(); +} diff --git a/src/app/qt/view/QtMainView.h b/src/app/qt/view/QtMainView.h index 900f418a..27342997 100644 --- a/src/app/qt/view/QtMainView.h +++ b/src/app/qt/view/QtMainView.h @@ -29,6 +29,9 @@ public: virtual QStatusBar* getStatusBar(); virtual void setStatusBar(QStatusBar* statusBar); + // MainView implementation + virtual void showStartScreen(); + private: std::shared_ptr m_window; std::vector m_views; diff --git a/src/app/qt/view/graphElements/QtGraphNodeData.cpp b/src/app/qt/view/graphElements/QtGraphNodeData.cpp index 7828be52..86eee87e 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/MessageActivateNode.h" +#include "utility/messaging/type/MessageActivateNodes.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" #include "utility/messaging/type/MessageGraphNodeMove.h" @@ -42,7 +42,9 @@ Id QtGraphNodeData::getTokenId() const void QtGraphNodeData::onClick() { - MessageActivateNode(m_data->getId(), m_data->getType(), m_data->getFullName()).dispatch(); + MessageActivateNodes message; + message.addNode(m_data->getId(), m_data->getType(), m_data->getFullName()); + message.dispatch(); } void QtGraphNodeData::moved(const Vec2i& oldPosition) diff --git a/src/app/qt/window/QtMainWindow.cpp b/src/app/qt/window/QtMainWindow.cpp index 30129d71..c7f93f24 100644 --- a/src/app/qt/window/QtMainWindow.cpp +++ b/src/app/qt/window/QtMainWindow.cpp @@ -53,11 +53,7 @@ void QtMainWindow::init() { ApplicationSettings* appSettings = ApplicationSettings::getInstance().get(); - if (appSettings->getUserHasSeenSettings()) - { - showStartScreen(); - } - else + if (!appSettings->getUserHasSeenSettings()) { openSettings(); m_startScreenWasVisible = true; diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 6546c2ee..6a1a8e1d 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -2,7 +2,7 @@ #include "utility/logging/logging.h" #include "utility/messaging/MessageQueue.h" -#include "utility/messaging/type/MessageActivateNode.h" +#include "utility/messaging/type/MessageActivateNodes.h" #include "utility/messaging/type/MessageStatus.h" #include "utility/scheduling/TaskScheduler.h" @@ -29,6 +29,16 @@ std::shared_ptr Application::create(ViewFactory* viewFactory) ptr->m_project = Project::create(ptr->m_storageCache.get()); + std::string startupProjectFilePath = ApplicationSettings::getInstance()->getStartupProjectFilePath(); + if (startupProjectFilePath.size()) + { + MessageLoadProject(startupProjectFilePath).dispatch(); + } + else + { + ptr->m_mainView->showStartScreen(); + } + return ptr; } @@ -108,7 +118,8 @@ void Application::handleMessage(MessageFinishedParsing* message) if (mainId) { - MessageActivateNode message( + MessageActivateNodes message; + message.addNode( mainId, m_storageCache->getNodeTypeForNodeWithId(mainId), m_storageCache->getNameForNodeWithId(mainId) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 166ade22..dc982325 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -233,8 +233,8 @@ add_files( utility/messaging/type/MessageActivateEdge.h utility/messaging/type/MessageActivateFile.h - utility/messaging/type/MessageActivateNode.h - utility/messaging/type/MessageActivateTokenLocation.h + utility/messaging/type/MessageActivateNodes.h + utility/messaging/type/MessageActivateTokenLocations.h utility/messaging/type/MessageActivateTokens.h utility/messaging/type/MessageAutoRefreshChanged.h utility/messaging/type/MessageFind.h diff --git a/src/lib/component/controller/FeatureController.cpp b/src/lib/component/controller/FeatureController.cpp index 64b86c43..84bb2b0c 100644 --- a/src/lib/component/controller/FeatureController.cpp +++ b/src/lib/component/controller/FeatureController.cpp @@ -66,35 +66,48 @@ void FeatureController::handleMessage(MessageActivateFile* message) m.dispatchImmediately(); } -void FeatureController::handleMessage(MessageActivateNode* message) +void FeatureController::handleMessage(MessageActivateNodes* message) { - Id nodeId = message->tokenId; - - if (!message->isFresh()) + std::vector nodeIds; + if (message->isFresh()) { - nodeId = m_storageAccess->getIdForNodeWithName(message->name); + for (const MessageActivateNodes::ActiveNode& node : message->nodes) + { + nodeIds.push_back(node.nodeId); + } + } + else + { + for (const MessageActivateNodes::ActiveNode& node : message->nodes) + { + nodeIds.push_back(m_storageAccess->getIdForNodeWithName(node.name)); + } } - if (nodeId) + if (nodeIds.size()) { - MessageActivateTokens m(nodeId); + MessageActivateTokens m(nodeIds); m.isFromSystem = message->isFromSystem; m.undoRedoType = message->undoRedoType; m.dispatchImmediately(); } } -void FeatureController::handleMessage(MessageActivateTokenLocation* message) +void FeatureController::handleMessage(MessageActivateTokenLocations* message) { - if (message->locationId) + std::vector nodeIds; + MessageActivateNodes msg; + + for (Id locationId : message->locationIds) { - Id nodeId = m_storageAccess->getActiveNodeIdForLocationId(message->locationId); - MessageActivateNode( + Id nodeId = m_storageAccess->getActiveNodeIdForLocationId(locationId); + msg.addNode( nodeId, m_storageAccess->getNodeTypeForNodeWithId(nodeId), m_storageAccess->getNameForNodeWithId(nodeId) - ).dispatchImmediately(); + ); } + msg.dispatchImmediately(); } void FeatureController::handleMessage(MessageSearch* message) diff --git a/src/lib/component/controller/FeatureController.h b/src/lib/component/controller/FeatureController.h index a7d782ba..c6de160d 100644 --- a/src/lib/component/controller/FeatureController.h +++ b/src/lib/component/controller/FeatureController.h @@ -4,8 +4,8 @@ #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/MessageActivateNodes.h" +#include "utility/messaging/type/MessageActivateTokenLocations.h" #include "utility/messaging/type/MessageSearch.h" #include "utility/messaging/type/MessageSwitchColorScheme.h" #include "utility/messaging/type/MessageZoom.h" @@ -18,8 +18,8 @@ class FeatureController : public Controller , public MessageListener , public MessageListener - , public MessageListener - , public MessageListener + , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -31,8 +31,8 @@ public: private: virtual void handleMessage(MessageActivateEdge* message); virtual void handleMessage(MessageActivateFile* message); - virtual void handleMessage(MessageActivateNode* message); - virtual void handleMessage(MessageActivateTokenLocation* message); + virtual void handleMessage(MessageActivateNodes* message); + virtual void handleMessage(MessageActivateTokenLocations* message); virtual void handleMessage(MessageSearch* message); virtual void handleMessage(MessageSwitchColorScheme* message); virtual void handleMessage(MessageZoom* message); diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index e9014dde..59ee2a8e 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -33,15 +33,21 @@ void SearchController::handleMessage(MessageActivateFile* message) getView()->setMatches(std::vector(1, match)); } -void SearchController::handleMessage(MessageActivateNode* message) +void SearchController::handleMessage(MessageActivateNodes* message) { - SearchMatch match; - match.fullName = message->name; - match.nodeType = message->type; - match.tokenIds.insert(message->tokenId); - match.searchType = SearchMatch::SEARCH_TOKEN; + std::vector matches; - getView()->setMatches(std::vector(1, match)); + for (const MessageActivateNodes::ActiveNode& node : message->nodes) + { + SearchMatch match; + match.fullName = node.name; + match.nodeType = node.type; + match.tokenIds.insert(node.nodeId); + match.searchType = SearchMatch::SEARCH_TOKEN; + matches.push_back(match); + } + + getView()->setMatches(matches); } void SearchController::handleMessage(MessageFind* message) diff --git a/src/lib/component/controller/SearchController.h b/src/lib/component/controller/SearchController.h index 5c179a05..454c30d2 100644 --- a/src/lib/component/controller/SearchController.h +++ b/src/lib/component/controller/SearchController.h @@ -7,7 +7,7 @@ #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/MessageActivateNodes.h" #include "utility/messaging/type/MessageFind.h" #include "utility/messaging/type/MessageFinishedParsing.h" #include "utility/messaging/type/MessageSearch.h" @@ -20,7 +20,7 @@ class SearchController : public Controller , public MessageListener , public MessageListener - , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -33,7 +33,7 @@ public: private: virtual void handleMessage(MessageActivateEdge* message); virtual void handleMessage(MessageActivateFile* message); - virtual void handleMessage(MessageActivateNode* message); + virtual void handleMessage(MessageActivateNodes* message); virtual void handleMessage(MessageFind* message); virtual void handleMessage(MessageFinishedParsing* message); virtual void handleMessage(MessageSearch* message); diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 9950a274..c1b7417b 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -49,15 +49,16 @@ void UndoRedoController::handleMessage(MessageActivateFile* message) processCommand(command); } -void UndoRedoController::handleMessage(MessageActivateNode* message) +void UndoRedoController::handleMessage(MessageActivateNodes* message) { - if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() && - static_cast(m_lastCommand.message.get())->name == message->name) + if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() && message->nodes.size() && + static_cast(m_lastCommand.message.get())->nodes.size() == message->nodes.size() && + static_cast(m_lastCommand.message.get())->nodes[0].name == message->nodes[0].name) { return; } - Command command(std::make_shared(*message), 0); + Command command(std::make_shared(*message), 0); processCommand(command); } diff --git a/src/lib/component/controller/UndoRedoController.h b/src/lib/component/controller/UndoRedoController.h index b00f2a57..35877ed5 100644 --- a/src/lib/component/controller/UndoRedoController.h +++ b/src/lib/component/controller/UndoRedoController.h @@ -7,7 +7,7 @@ #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/MessageActivateNodes.h" #include "utility/messaging/type/MessageGraphNodeBundleSplit.h" #include "utility/messaging/type/MessageGraphNodeExpand.h" #include "utility/messaging/type/MessageGraphNodeMove.h" @@ -27,7 +27,7 @@ class UndoRedoController : public Controller , public MessageListener , public MessageListener - , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -56,7 +56,7 @@ private: virtual void handleMessage(MessageActivateEdge* message); virtual void handleMessage(MessageActivateFile* message); - virtual void handleMessage(MessageActivateNode* message); + virtual void handleMessage(MessageActivateNodes* message); virtual void handleMessage(MessageGraphNodeBundleSplit* message); virtual void handleMessage(MessageGraphNodeExpand* message); virtual void handleMessage(MessageGraphNodeMove* message); diff --git a/src/lib/component/view/MainView.h b/src/lib/component/view/MainView.h index 7925681e..84a4e69b 100644 --- a/src/lib/component/view/MainView.h +++ b/src/lib/component/view/MainView.h @@ -9,6 +9,7 @@ public: MainView(); virtual ~MainView(); + virtual void showStartScreen() = 0; }; #endif // MAIN_VIEW_H diff --git a/src/lib/utility/messaging/type/MessageActivateNode.h b/src/lib/utility/messaging/type/MessageActivateNode.h deleted file mode 100644 index a3de8cc7..00000000 --- a/src/lib/utility/messaging/type/MessageActivateNode.h +++ /dev/null @@ -1,33 +0,0 @@ -#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/MessageActivateNodes.h b/src/lib/utility/messaging/type/MessageActivateNodes.h new file mode 100644 index 00000000..89fae329 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateNodes.h @@ -0,0 +1,45 @@ +#ifndef MESSAGE_ACTIVATE_NODES_H +#define MESSAGE_ACTIVATE_NODES_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +#include "data/graph/Node.h" + +class MessageActivateNodes + : public Message +{ +public: + struct ActiveNode + { + Id nodeId; + Node::NodeType type; + std::string name; + }; + + MessageActivateNodes() + : isFromSystem(false) + { + } + + void addNode(Id tokenId, Node::NodeType type, const std::string& name) + { + ActiveNode node; + node.nodeId = tokenId; + node.type = type; + node.name = name; + + nodes.push_back(node); + } + + static const std::string getStaticType() + { + return "MessageActivateNodes"; + } + + std::vector nodes; + + bool isFromSystem; +}; + +#endif // MESSAGE_ACTIVATE_NODES_H diff --git a/src/lib/utility/messaging/type/MessageActivateTokenLocation.h b/src/lib/utility/messaging/type/MessageActivateTokenLocation.h deleted file mode 100644 index d534e7e5..00000000 --- a/src/lib/utility/messaging/type/MessageActivateTokenLocation.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef MESSAGE_ACTIVATE_TOKEN_LOCATION_H -#define MESSAGE_ACTIVATE_TOKEN_LOCATION_H - -#include "utility/messaging/Message.h" -#include "utility/types.h" - -class MessageActivateTokenLocation: public Message -{ -public: - MessageActivateTokenLocation(Id locationId) - : locationId(locationId) - { - } - - static const std::string getStaticType() - { - return "MessageActivateTokenLocation"; - } - - const Id locationId; -}; - -#endif // MESSAGE_ACTIVATE_TOKEN_LOCATION_H diff --git a/src/lib/utility/messaging/type/MessageActivateTokenLocations.h b/src/lib/utility/messaging/type/MessageActivateTokenLocations.h new file mode 100644 index 00000000..5040ec7b --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateTokenLocations.h @@ -0,0 +1,24 @@ +#ifndef MESSAGE_ACTIVATE_TOKEN_LOCATIONS_H +#define MESSAGE_ACTIVATE_TOKEN_LOCATIONS_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +class MessageActivateTokenLocations + : public Message +{ +public: + MessageActivateTokenLocations(const std::vector& locationIds) + : locationIds(locationIds) + { + } + + static const std::string getStaticType() + { + return "MessageActivateTokenLocations"; + } + + const std::vector locationIds; +}; + +#endif // MESSAGE_ACTIVATE_TOKEN_LOCATIONS_H diff --git a/src/lib/utility/messaging/type/MessageActivateTokens.h b/src/lib/utility/messaging/type/MessageActivateTokens.h index 923669a0..d62ff8f1 100644 --- a/src/lib/utility/messaging/type/MessageActivateTokens.h +++ b/src/lib/utility/messaging/type/MessageActivateTokens.h @@ -4,7 +4,8 @@ #include "utility/messaging/Message.h" #include "utility/types.h" -class MessageActivateTokens: public Message +class MessageActivateTokens + : public Message { public: MessageActivateTokens(const std::vector& tokenIds)