From ad6f5c8727ec62dbbd71e6d68c04103147bdc4c3 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Sun, 22 Jul 2018 14:30:56 +0200 Subject: [PATCH] ui: Added show definition context menu action for graph nodes (issue #83) * use 'show definition' context menu action or 'Ctrl/Cmd + Left Click' to show definition of node in code --- src/lib/CMakeLists.txt | 2 + .../component/controller/CodeController.cpp | 111 +++++++++++++++--- src/lib/component/controller/CodeController.h | 3 + .../controller/UndoRedoController.cpp | 12 ++ .../component/controller/UndoRedoController.h | 3 + .../location/SourceLocationCollection.cpp | 31 ++++- .../data/location/SourceLocationCollection.h | 7 +- src/lib/data/location/SourceLocationFile.cpp | 15 +++ src/lib/data/storage/PersistentStorage.cpp | 4 +- .../type/code/MessageCodeShowDefinition.h | 29 +++++ src/lib_gui/qt/element/QtCodeFile.cpp | 33 +++--- src/lib_gui/qt/graphics/QtGraphicsView.cpp | 48 +++++--- src/lib_gui/qt/graphics/QtGraphicsView.h | 2 + .../qt/view/graphElements/QtGraphNode.cpp | 15 +++ .../qt/view/graphElements/QtGraphNode.h | 1 + .../QtGraphNodeComponentClickable.cpp | 4 + 16 files changed, 267 insertions(+), 53 deletions(-) create mode 100644 src/lib/utility/messaging/type/code/MessageCodeShowDefinition.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index d3b43db5..85b46525 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -418,6 +418,8 @@ add_files( utility/messaging/filter_types/MessageFilterFocusInOut.h utility/messaging/filter_types/MessageFilterSearchAutocomplete.h + utility/messaging/type/code/MessageCodeShowDefinition.h + utility/messaging/type/error/MessageActivateErrors.h utility/messaging/type/error/MessageErrorCountClear.h utility/messaging/type/error/MessageErrorCountUpdate.h diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 209ab92d..6c1b66d0 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -287,6 +287,91 @@ void CodeController::handleMessage(MessageChangeFileView* message) } } +void CodeController::handleMessage(MessageCodeShowDefinition* message) +{ + TRACE("code show definition"); + + Id nodeId = message->nodeId; + + std::shared_ptr collection = m_storageAccess->getSourceLocationsForTokenIds({ nodeId }); + if (!collection->getSourceLocationFileCount()) + { + LOG_ERROR("MessageCodeShowDefinition did not contain a nodeId with location files."); + return; + } + + size_t lineNumber = 1; + FilePath filePath; + + // use first scope location for nodeId, otherwise first location + if (collection->getSourceLocationCount()) + { + std::shared_ptr filteredCollection = std::make_shared(); + bool addedLocation = false; + + collection->forEachSourceLocation( + [&](SourceLocation* location) + { + if (addedLocation || !location->isStartLocation()) + { + return; + } + + if (location->isScopeLocation()) + { + filteredCollection->addSourceLocationCopy(location); + filteredCollection->addSourceLocationCopy(location->getEndLocation()); + + filePath = location->getFilePath(); + lineNumber = location->getLineNumber(); + addedLocation = true; + return; + } + } + ); + + if (!addedLocation) + { + SourceLocation* location = collection->getSourceLocationFiles().begin()->second->getSourceLocations().begin()->get(); + filteredCollection->addSourceLocationCopy(location); + filteredCollection->addSourceLocationCopy(location->getOtherLocation()); + + filePath = location->getFilePath(); + lineNumber = location->getStartLocation()->getLineNumber(); + } + + collection = filteredCollection; + } + else // otherwise first file + { + filePath = collection->getSourceLocationFiles().begin()->second->getFilePath(); + } + + std::vector snippets = getSnippetsForFile(collection->getSourceLocationFiles().begin()->second); + if (snippets.size() != 1) + { + LOG_ERROR("MessageCodeShowDefinition snippet count is not 1"); + return; + } + + snippets[0].insertSnippet = true; + m_collection->addSourceLocationCopies(collection.get()); + + saveOrRestoreViewMode(message); + + CodeView* view = getView(); + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_LINE); + scrollParams.filePath = filePath; + scrollParams.line = lineNumber; + view->scrollTo(scrollParams); + + CodeView::CodeParams params; + params.showContents = !message->isReplayed(); + + addAllSourceLocations(&snippets); + getView()->showCodeSnippets(snippets, params); +} + void CodeController::handleMessage(MessageDeactivateEdge* message) { if (message->scrollToDefinition) @@ -394,7 +479,7 @@ void CodeController::clear() { getView()->clear(); - m_collection.reset(); + m_collection = std::make_shared(); } std::vector CodeController::getSnippetsForFileWithState( @@ -402,20 +487,18 @@ std::vector CodeController::getSnippetsForFileWithState( { TRACE(); + std::shared_ptr file = m_collection->getSourceLocationFileByPath(filePath); + if (!file) + { + return {}; + } + std::vector snippets; switch (state) { case CodeView::FILE_SNIPPETS: - { - std::shared_ptr file = m_collection->getSourceLocationFileByPath(filePath); - if (!file) - { - return snippets; - } - - snippets = getSnippetsForFile(file); - } + snippets = getSnippetsForFile(file); break; case CodeView::FILE_MAXIMIZED: @@ -431,12 +514,8 @@ std::vector CodeController::getSnippetsForFileWithState( // make a copy of SourceLocationFile so that isWhole flag is different for first snippet adding the file // and second snippet adding the content - params.locationFile = - std::make_shared(*m_collection->getSourceLocationFileByPath(filePath).get()); - if (params.locationFile) - { - params.locationFile->setIsWhole(true); - } + params.locationFile = std::make_shared(*file.get()); + params.locationFile->setIsWhole(true); snippets.push_back(params); } diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index ffa6d5dd..e0edc284 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -6,6 +6,7 @@ #include "utility/file/FilePath.h" #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/error/MessageActivateErrors.h" #include "utility/messaging/type/error/MessageErrorCountClear.h" #include "utility/messaging/type/error/MessageShowError.h" @@ -42,6 +43,7 @@ class CodeController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -66,6 +68,7 @@ private: virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageActivateTrailEdge* message); virtual void handleMessage(MessageChangeFileView* message); + virtual void handleMessage(MessageCodeShowDefinition* message); virtual void handleMessage(MessageDeactivateEdge* message); virtual void handleMessage(MessageErrorCountClear* message); virtual void handleMessage(MessageFlushUpdates* message); diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 540bd61b..fc8ac05f 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -139,6 +139,18 @@ void UndoRedoController::handleMessage(MessageChangeFileView* message) processCommand(command); } +void UndoRedoController::handleMessage(MessageCodeShowDefinition* message) +{ + if (sameMessageTypeAsLast(message) && + static_cast(lastMessage())->nodeId == message->nodeId) + { + return; + } + + Command command(std::make_shared(*message), Command::ORDER_ADAPT); + processCommand(command); +} + void UndoRedoController::handleMessage(MessageDeactivateEdge* message) { if (m_iterator == m_list.begin()) diff --git a/src/lib/component/controller/UndoRedoController.h b/src/lib/component/controller/UndoRedoController.h index 5c13c0fb..dd3a8735 100644 --- a/src/lib/component/controller/UndoRedoController.h +++ b/src/lib/component/controller/UndoRedoController.h @@ -5,6 +5,7 @@ #include "utility/messaging/MessageBase.h" #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/error/MessageActivateErrors.h" #include "utility/messaging/type/error/MessageShowError.h" #include "utility/messaging/type/history/MessageHistoryRedo.h" @@ -44,6 +45,7 @@ class UndoRedoController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -93,6 +95,7 @@ private: virtual void handleMessage(MessageActivateTrail* message); virtual void handleMessage(MessageActivateTrailEdge* message); virtual void handleMessage(MessageChangeFileView* message); + virtual void handleMessage(MessageCodeShowDefinition* message); virtual void handleMessage(MessageDeactivateEdge* message); virtual void handleMessage(MessageGraphNodeBundleSplit* message); virtual void handleMessage(MessageGraphNodeExpand* message); diff --git a/src/lib/data/location/SourceLocationCollection.cpp b/src/lib/data/location/SourceLocationCollection.cpp index a5527c11..9e99429c 100644 --- a/src/lib/data/location/SourceLocationCollection.cpp +++ b/src/lib/data/location/SourceLocationCollection.cpp @@ -78,9 +78,30 @@ SourceLocation* SourceLocationCollection::addSourceLocation( return file->addSourceLocation(type, locationId, tokenIds, startLineNumber, startColumnNumber, endLineNumber, endColumnNumber); } -SourceLocation* SourceLocationCollection::addSourceLocationCopy(SourceLocation* location) +SourceLocation* SourceLocationCollection::addSourceLocationCopy(const SourceLocation* location) { - return createSourceLocationFile(location->getFilePath())->addSourceLocationCopy(location); + SourceLocationFile* other = location->getSourceLocationFile(); + SourceLocationFile* file = + createSourceLocationFile(location->getFilePath(), other->isWhole(), other->isComplete(), other->isIndexed()); + return file->addSourceLocationCopy(location); +} + +void SourceLocationCollection::addSourceLocationCopies(const SourceLocationCollection* other) +{ + other->forEachSourceLocationFile( + [this](std::shared_ptr otherFile) + { + SourceLocationFile* file = createSourceLocationFile( + otherFile->getFilePath(), otherFile->isWhole(), otherFile->isComplete(), otherFile->isIndexed()); + + otherFile->forEachSourceLocation( + [file](SourceLocation* otherLocation) + { + file->addSourceLocationCopy(otherLocation); + } + ); + } + ); } void SourceLocationCollection::addSourceLocationFile(std::shared_ptr file) @@ -105,7 +126,8 @@ void SourceLocationCollection::forEachSourceLocation(std::function filePtr = std::make_shared(filePath, false, false, false); + std::shared_ptr filePtr = + std::make_shared(filePath, isWhole, isComplete, isIndexed); m_files.emplace(filePath, filePtr); return filePtr.get(); } diff --git a/src/lib/data/location/SourceLocationCollection.h b/src/lib/data/location/SourceLocationCollection.h index 89f1129a..8fcfce48 100644 --- a/src/lib/data/location/SourceLocationCollection.h +++ b/src/lib/data/location/SourceLocationCollection.h @@ -32,7 +32,9 @@ public: LocationType type, Id locationId, std::vector tokenIds, const FilePath& filePath, size_t startLineNumber, size_t startColumnNumber, size_t endLineNumber, size_t endColumnNumber); - SourceLocation* addSourceLocationCopy(SourceLocation* location); + + SourceLocation* addSourceLocationCopy(const SourceLocation* location); + void addSourceLocationCopies(const SourceLocationCollection* other); void addSourceLocationFile(std::shared_ptr file); @@ -40,7 +42,8 @@ public: void forEachSourceLocation(std::function func) const; private: - SourceLocationFile* createSourceLocationFile(const FilePath& filePath); + SourceLocationFile* createSourceLocationFile( + const FilePath& filePath, bool isWhole = false, bool isComplete = false, bool isIndexed = false); std::map> m_files; }; diff --git a/src/lib/data/location/SourceLocationFile.cpp b/src/lib/data/location/SourceLocationFile.cpp index b4f092c8..68a976e9 100644 --- a/src/lib/data/location/SourceLocationFile.cpp +++ b/src/lib/data/location/SourceLocationFile.cpp @@ -215,6 +215,21 @@ std::wostream& operator<<(std::wostream& ostream, const SourceLocationFile& file { ostream << L"file \"" << file.getFilePath().wstr() << L"\""; + if (file.isWhole()) + { + ostream << L" whole"; + } + + if (file.isComplete()) + { + ostream << L" complete"; + } + + if (file.isIndexed()) + { + ostream << L" indexed"; + } + size_t line = 0; file.forEachSourceLocation( [&ostream, &line](SourceLocation* location) diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index 640cc7f2..d5a90059 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -1380,6 +1380,7 @@ std::shared_ptr PersistentStorage::getSourceLocationsF if (nonFileIds.size()) { + // FIXME: can we use get SqliteIndexStorage::getSourceLocationsForElementIds() here instead? std::vector locationIds; std::unordered_map locationIdToElementIdMap; for (const StorageOccurrence& occurrence: m_sqliteIndexStorage.getOccurrencesForElementIds(nonFileIds)) @@ -1403,6 +1404,7 @@ std::shared_ptr PersistentStorage::getSourceLocationsF } FilePath path = getFileNodePath(sourceLocation.fileNodeId); + // FIXME: This shouldn't be necessary since all files are stored, even non-indexed if (path.empty()) { const StorageNode fileNode = m_sqliteIndexStorage.getNodeById(sourceLocation.fileNodeId); @@ -1421,7 +1423,7 @@ std::shared_ptr PersistentStorage::getSourceLocationsF collection->addSourceLocation( type, sourceLocation.id, - std::vector(1, it->second), + { it->second }, path, sourceLocation.startLine, sourceLocation.startCol, diff --git a/src/lib/utility/messaging/type/code/MessageCodeShowDefinition.h b/src/lib/utility/messaging/type/code/MessageCodeShowDefinition.h new file mode 100644 index 00000000..71fd9f64 --- /dev/null +++ b/src/lib/utility/messaging/type/code/MessageCodeShowDefinition.h @@ -0,0 +1,29 @@ +#ifndef MESSAGE_CODE_SHOW_DEFINITION_H +#define MESSAGE_CODE_SHOW_DEFINITION_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +class MessageCodeShowDefinition + : public Message +{ +public: + static const std::string getStaticType() + { + return "MessageCodeShowDefinition"; + } + + MessageCodeShowDefinition(Id nodeId) + : nodeId(nodeId) + { + } + + virtual void print(std::wostream& os) const + { + os << nodeId; + } + + const Id nodeId; +}; + +#endif // MESSAGE_CODE_SHOW_DEFINITION_H diff --git a/src/lib_gui/qt/element/QtCodeFile.cpp b/src/lib_gui/qt/element/QtCodeFile.cpp index 1eb37902..2d7febc9 100644 --- a/src/lib_gui/qt/element/QtCodeFile.cpp +++ b/src/lib_gui/qt/element/QtCodeFile.cpp @@ -120,44 +120,49 @@ QtCodeSnippet* QtCodeFile::addCodeSnippet(const CodeSnippetParams& params) QtCodeSnippet* QtCodeFile::insertCodeSnippet(const CodeSnippetParams& params) { - QtCodeSnippet* snippet = new QtCodeSnippet(params, m_navigator, this); + QtCodeSnippet* newSnippet = new QtCodeSnippet(params, m_navigator, this); size_t i = 0; while (i < m_snippets.size()) { - uint start = snippet->getStartLineNumber(); - uint end = snippet->getEndLineNumber(); + uint start = newSnippet->getStartLineNumber(); + uint end = newSnippet->getEndLineNumber(); - QtCodeSnippet* s = m_snippets[i]; + QtCodeSnippet* oldSnippet = m_snippets[i]; - if (s->getEndLineNumber() + 1 < start) + if (oldSnippet->getEndLineNumber() + 1 < start) // before { i++; continue; } - else if (s->getStartLineNumber() > end + 1) + else if (oldSnippet->getStartLineNumber() > end + 1) // after { break; } - else if (s->getStartLineNumber() < start || s->getEndLineNumber() > end) + else if (oldSnippet->getStartLineNumber() <= start && oldSnippet->getEndLineNumber() >= end) // containing + { + newSnippet->deleteLater(); + return oldSnippet; + } + else if (oldSnippet->getStartLineNumber() < start || oldSnippet->getEndLineNumber() > end) // overlaping { m_navigator->clearSnippetReferences(); - snippet = QtCodeSnippet::merged(snippet, s, m_navigator, this); + newSnippet = QtCodeSnippet::merged(newSnippet, oldSnippet, m_navigator, this); } - s->hide(); - m_snippetLayout->removeWidget(s); - s->deleteLater(); + oldSnippet->hide(); + m_snippetLayout->removeWidget(oldSnippet); + oldSnippet->deleteLater(); m_snippets.erase(m_snippets.begin() + i); } - m_snippetLayout->insertWidget(i, snippet); - m_snippets.insert(m_snippets.begin() + i, snippet); + m_snippetLayout->insertWidget(i, newSnippet); + m_snippets.insert(m_snippets.begin() + i, newSnippet); setSnippets(); - return snippet; + return newSnippet; } void QtCodeFile::updateCodeSnippet(const CodeSnippetParams& params) diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.cpp b/src/lib_gui/qt/graphics/QtGraphicsView.cpp index bc9d6239..69fc2737 100644 --- a/src/lib_gui/qt/graphics/QtGraphicsView.cpp +++ b/src/lib_gui/qt/graphics/QtGraphicsView.cpp @@ -20,6 +20,7 @@ #include "qt/utility/QtFileDialog.h" #include "qt/utility/utilityQt.h" #include "settings/ApplicationSettings.h" +#include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/MessageDisplayBookmarkCreator.h" #include "utility/messaging/type/MessageGraphNodeHide.h" #include "utility/ResourcePaths.h" @@ -51,29 +52,37 @@ QtGraphicsView::QtGraphicsView(QWidget* parent) m_zoomLabelTimer = std::make_shared(this); connect(m_zoomLabelTimer.get(), &QTimer::timeout, this, &QtGraphicsView::hideZoomLabel); - m_exportGraphAction = new QAction(tr("Save as Image"), this); - m_exportGraphAction->setStatusTip(tr("Save this graph as image file")); - m_exportGraphAction->setToolTip(tr("Save this graph as image file")); + m_exportGraphAction = new QAction("Save as Image", this); + m_exportGraphAction->setStatusTip("Save this graph as image file"); + m_exportGraphAction->setToolTip("Save this graph as image file"); connect(m_exportGraphAction, &QAction::triggered, this, &QtGraphicsView::exportGraph); - m_copyNodeNameAction = new QAction(tr("Copy Name"), this); - m_copyNodeNameAction->setStatusTip(tr("Copies the name of this node to the clipboard")); - m_copyNodeNameAction->setToolTip(tr("Copies the name of this node to the clipboard")); + m_copyNodeNameAction = new QAction("Copy Name", this); + m_copyNodeNameAction->setStatusTip("Copies the name of this node to the clipboard"); + m_copyNodeNameAction->setToolTip("Copies the name of this node to the clipboard"); connect(m_copyNodeNameAction, &QAction::triggered, this, &QtGraphicsView::copyNodeName); - m_hideNodeAction = new QAction(tr("Hide Node (Alt + Left Click)"), this); - m_hideNodeAction->setStatusTip(tr("Hide the node from this graph")); - m_hideNodeAction->setToolTip(tr("Hide the node from this graph")); + m_showDefinitionAction = new QAction("Show Definition (Ctrl + Left Click)", this); +#if defined(Q_OS_MAC) + m_showDefinitionAction->setText("Show Definition (Cmd + Left Click)"); +#endif + m_showDefinitionAction->setStatusTip("Show definition of this symbol in the code"); + m_showDefinitionAction->setToolTip("Show definition of this symbol in the code"); + connect(m_showDefinitionAction, &QAction::triggered, this, &QtGraphicsView::showDefinition); + + m_hideNodeAction = new QAction("Hide Node (Alt + Left Click)", this); + m_hideNodeAction->setStatusTip("Hide the node from this graph"); + m_hideNodeAction->setToolTip("Hide the node from this graph"); connect(m_hideNodeAction, &QAction::triggered, this, &QtGraphicsView::hideNode); - m_hideEdgeAction = new QAction(tr("Hide Edge (Alt + Left Click)"), this); - m_hideEdgeAction->setStatusTip(tr("Hide the edge from this graph")); - m_hideEdgeAction->setToolTip(tr("Hide the edge from this graph")); + m_hideEdgeAction = new QAction("Hide Edge (Alt + Left Click)", this); + m_hideEdgeAction->setStatusTip("Hide the edge from this graph"); + m_hideEdgeAction->setToolTip("Hide the edge from this graph"); connect(m_hideEdgeAction, &QAction::triggered, this, &QtGraphicsView::hideEdge); - m_bookmarkNodeAction = new QAction(tr("Bookmark Node"), this); - m_bookmarkNodeAction->setStatusTip(tr("Create a bookmark for this node")); - m_bookmarkNodeAction->setToolTip(tr("Create a bookmark for this node")); + m_bookmarkNodeAction = new QAction("Bookmark Node", this); + m_bookmarkNodeAction->setStatusTip("Create a bookmark for this node"); + m_bookmarkNodeAction->setToolTip("Create a bookmark for this node"); connect(m_bookmarkNodeAction, &QAction::triggered, this, &QtGraphicsView::bookmarkNode); m_zoomState = new QPushButton(this); @@ -354,6 +363,7 @@ void QtGraphicsView::contextMenuEvent(QContextMenuEvent* event) } } + m_showDefinitionAction->setEnabled(m_hideNodeId); m_hideNodeAction->setEnabled(m_hideNodeId); m_hideEdgeAction->setEnabled(m_hideEdgeId); m_bookmarkNodeAction->setEnabled(m_bookmarkNodeId); @@ -366,8 +376,9 @@ void QtGraphicsView::contextMenuEvent(QContextMenuEvent* event) menu.addAction(m_exportGraphAction); menu.addSeparator(); - menu.addAction(m_hideEdgeAction); + menu.addAction(m_showDefinitionAction); menu.addAction(m_hideNodeAction); + menu.addAction(m_hideEdgeAction); menu.addAction(m_bookmarkNodeAction); menu.addSeparator(); @@ -521,6 +532,11 @@ void QtGraphicsView::copyNodeName() QApplication::clipboard()->setText(QString::fromStdWString(m_clipboardNodeName)); } +void QtGraphicsView::showDefinition() +{ + MessageCodeShowDefinition(m_hideNodeId).dispatch(); +} + void QtGraphicsView::hideNode() { MessageGraphNodeHide(m_hideNodeId).dispatch(); diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.h b/src/lib_gui/qt/graphics/QtGraphicsView.h index 4de03ca4..1b2da07f 100644 --- a/src/lib_gui/qt/graphics/QtGraphicsView.h +++ b/src/lib_gui/qt/graphics/QtGraphicsView.h @@ -57,6 +57,7 @@ private slots: void exportGraph(); void copyNodeName(); + void showDefinition(); void hideNode(); void hideEdge(); void bookmarkNode(); @@ -94,6 +95,7 @@ private: QAction* m_exportGraphAction; QAction* m_copyNodeNameAction; + QAction* m_showDefinitionAction; QAction* m_hideNodeAction; QAction* m_hideEdgeAction; QAction* m_bookmarkNodeAction; diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp index 1e53d41e..f9a9ed60 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp @@ -11,6 +11,7 @@ #include "qt/utility/utilityQt.h" #include "qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h" #include "qt/view/graphElements/QtGraphEdge.h" +#include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/MessageGraphNodeHide.h" #include "utility/messaging/type/MessageGraphNodeMove.h" #include "utility/ResourcePaths.h" @@ -400,6 +401,20 @@ void QtGraphNode::onHide() } } +void QtGraphNode::onShowDefinition() +{ + Id tokenId = getTokenId(); + + if (tokenId) + { + MessageCodeShowDefinition(tokenId).dispatch(); + } + else if (getParent()) + { + getParent()->onShowDefinition(); + } +} + void QtGraphNode::mousePressEvent(QGraphicsSceneMouseEvent* event) { event->ignore(); diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNode.h b/src/lib_gui/qt/view/graphElements/QtGraphNode.h index 9ad7b152..eec3cc79 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNode.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNode.h @@ -98,6 +98,7 @@ public: virtual void onClick(); virtual void onHide(); + virtual void onShowDefinition(); virtual void moved(const Vec2i& oldPosition); virtual void updateStyle() = 0; diff --git a/src/lib_gui/qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.cpp b/src/lib_gui/qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.cpp index 83c6b1dc..e749f1f9 100644 --- a/src/lib_gui/qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.cpp +++ b/src/lib_gui/qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.cpp @@ -39,6 +39,10 @@ void QtGraphNodeComponentClickable::nodeMouseReleaseEvent(QGraphicsSceneMouseEve { m_graphNode->onHide(); } + else if (event->modifiers() & Qt::ControlModifier) + { + m_graphNode->onShowDefinition(); + } else { m_graphNode->onClick();