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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<SourceLocationCollection> 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<SourceLocationCollection> filteredCollection = std::make_shared<SourceLocationCollection>();
|
||||
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<CodeSnippetParams> 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<SourceLocationCollection>();
|
||||
}
|
||||
|
||||
std::vector<CodeSnippetParams> CodeController::getSnippetsForFileWithState(
|
||||
@@ -402,20 +487,18 @@ std::vector<CodeSnippetParams> CodeController::getSnippetsForFileWithState(
|
||||
{
|
||||
TRACE();
|
||||
|
||||
std::shared_ptr<SourceLocationFile> file = m_collection->getSourceLocationFileByPath(filePath);
|
||||
if (!file)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CodeSnippetParams> snippets;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CodeView::FILE_SNIPPETS:
|
||||
{
|
||||
std::shared_ptr<SourceLocationFile> 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<CodeSnippetParams> 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<SourceLocationFile>(*m_collection->getSourceLocationFileByPath(filePath).get());
|
||||
if (params.locationFile)
|
||||
{
|
||||
params.locationFile->setIsWhole(true);
|
||||
}
|
||||
params.locationFile = std::make_shared<SourceLocationFile>(*file.get());
|
||||
params.locationFile->setIsWhole(true);
|
||||
|
||||
snippets.push_back(params);
|
||||
}
|
||||
|
||||
@@ -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<MessageActivateTokens>
|
||||
, public MessageListener<MessageActivateTrailEdge>
|
||||
, public MessageListener<MessageChangeFileView>
|
||||
, public MessageListener<MessageCodeShowDefinition>
|
||||
, public MessageListener<MessageDeactivateEdge>
|
||||
, public MessageListener<MessageErrorCountClear>
|
||||
, public MessageListener<MessageFlushUpdates>
|
||||
@@ -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);
|
||||
|
||||
@@ -139,6 +139,18 @@ void UndoRedoController::handleMessage(MessageChangeFileView* message)
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void UndoRedoController::handleMessage(MessageCodeShowDefinition* message)
|
||||
{
|
||||
if (sameMessageTypeAsLast(message) &&
|
||||
static_cast<MessageCodeShowDefinition*>(lastMessage())->nodeId == message->nodeId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Command command(std::make_shared<MessageCodeShowDefinition>(*message), Command::ORDER_ADAPT);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void UndoRedoController::handleMessage(MessageDeactivateEdge* message)
|
||||
{
|
||||
if (m_iterator == m_list.begin())
|
||||
|
||||
@@ -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<MessageActivateTrail>
|
||||
, public MessageListener<MessageActivateTrailEdge>
|
||||
, public MessageListener<MessageChangeFileView>
|
||||
, public MessageListener<MessageCodeShowDefinition>
|
||||
, public MessageListener<MessageDeactivateEdge>
|
||||
, public MessageListener<MessageGraphNodeBundleSplit>
|
||||
, public MessageListener<MessageGraphNodeExpand>
|
||||
@@ -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);
|
||||
|
||||
@@ -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<SourceLocationFile> 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<SourceLocationFile> file)
|
||||
@@ -105,7 +126,8 @@ void SourceLocationCollection::forEachSourceLocation(std::function<void(SourceLo
|
||||
}
|
||||
}
|
||||
|
||||
SourceLocationFile* SourceLocationCollection::createSourceLocationFile(const FilePath& filePath)
|
||||
SourceLocationFile* SourceLocationCollection::createSourceLocationFile(
|
||||
const FilePath& filePath, bool isWhole, bool isComplete, bool isIndexed)
|
||||
{
|
||||
SourceLocationFile* file = getSourceLocationFileByPath(filePath).get();
|
||||
if (file)
|
||||
@@ -113,7 +135,8 @@ SourceLocationFile* SourceLocationCollection::createSourceLocationFile(const Fil
|
||||
return file;
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceLocationFile> filePtr = std::make_shared<SourceLocationFile>(filePath, false, false, false);
|
||||
std::shared_ptr<SourceLocationFile> filePtr =
|
||||
std::make_shared<SourceLocationFile>(filePath, isWhole, isComplete, isIndexed);
|
||||
m_files.emplace(filePath, filePtr);
|
||||
return filePtr.get();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@ public:
|
||||
LocationType type, Id locationId, std::vector<Id> 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<SourceLocationFile> file);
|
||||
|
||||
@@ -40,7 +42,8 @@ public:
|
||||
void forEachSourceLocation(std::function<void(SourceLocation*)> func) const;
|
||||
|
||||
private:
|
||||
SourceLocationFile* createSourceLocationFile(const FilePath& filePath);
|
||||
SourceLocationFile* createSourceLocationFile(
|
||||
const FilePath& filePath, bool isWhole = false, bool isComplete = false, bool isIndexed = false);
|
||||
|
||||
std::map<FilePath, std::shared_ptr<SourceLocationFile>> m_files;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1380,6 +1380,7 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getSourceLocationsF
|
||||
|
||||
if (nonFileIds.size())
|
||||
{
|
||||
// FIXME: can we use get SqliteIndexStorage::getSourceLocationsForElementIds() here instead?
|
||||
std::vector<Id> locationIds;
|
||||
std::unordered_map<Id, Id> locationIdToElementIdMap;
|
||||
for (const StorageOccurrence& occurrence: m_sqliteIndexStorage.getOccurrencesForElementIds(nonFileIds))
|
||||
@@ -1403,6 +1404,7 @@ std::shared_ptr<SourceLocationCollection> 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<SourceLocationCollection> PersistentStorage::getSourceLocationsF
|
||||
collection->addSourceLocation(
|
||||
type,
|
||||
sourceLocation.id,
|
||||
std::vector<Id>(1, it->second),
|
||||
{ it->second },
|
||||
path,
|
||||
sourceLocation.startLine,
|
||||
sourceLocation.startCol,
|
||||
|
||||
@@ -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<MessageCodeShowDefinition>
|
||||
{
|
||||
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
|
||||
@@ -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)
|
||||
|
||||
@@ -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<QTimer>(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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
|
||||
virtual void onClick();
|
||||
virtual void onHide();
|
||||
virtual void onShowDefinition();
|
||||
virtual void moved(const Vec2i& oldPosition);
|
||||
|
||||
virtual void updateStyle() = 0;
|
||||
|
||||
@@ -39,6 +39,10 @@ void QtGraphNodeComponentClickable::nodeMouseReleaseEvent(QGraphicsSceneMouseEve
|
||||
{
|
||||
m_graphNode->onHide();
|
||||
}
|
||||
else if (event->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
m_graphNode->onShowDefinition();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphNode->onClick();
|
||||
|
||||
Reference in New Issue
Block a user