diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index de1d1319..fe348b06 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -42,47 +42,20 @@ Edge.cpp ERROR: Nodes are not plain copies. INFO: Indexer - indexing source file: input.cc INFO: Indexer - indexing source file: input.cc INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage2 - INFO: handle TestMessage2 INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage2 - INFO: handle TestMessage2 INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage2 - INFO: handle TestMessage2 INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage INFO: send TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage - INFO: handle TestMessage NetworkProtocolHelper.cpp ERROR: Failed to parse message, invalid type token: foo. Expected setActiveToken NetworkProtocolHelper.cpp ERROR: Failed to parse setActiveToken message, invalid token count Settings.cpp WARNING: File for Settings not found: data/SettingsTestSuite/wrong_settings.xml diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f24ad857..c8c35650 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -262,6 +262,7 @@ add_files( utility/messaging/type/MessageClearLogView.h utility/messaging/type/MessageClearStatusView.h utility/messaging/type/MessageCodeReference.h + utility/messaging/type/MessageCodeViewExpandedInitialFiles.h utility/messaging/type/MessageColorSchemeTest.h utility/messaging/type/MessageDeactivateEdge.h utility/messaging/type/MessageDispatchWhenLicenseValid.h diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index bdec80b2..19fe39b8 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -18,6 +18,8 @@ CodeController::CodeController(StorageAccess* storageAccess) : m_storageAccess(storageAccess) + , m_scrollToDefinition(false) + , m_scrollToValue(-1) { } @@ -131,6 +133,7 @@ void CodeController::handleMessage(MessageActivateTokens* message) { m_collection = m_storageAccess->getTokenLocationsForTokenIds(activeTokenIds); view->showCodeSnippets(getSnippetsForActiveTokenLocations(m_collection.get(), declarationId), activeTokenIds, true); + m_scrollToDefinition = !message->isReplayed() || message->isLast(); size_t fileCount = m_collection->getTokenLocationFileCount(); size_t referenceCount = m_collection->getTokenLocationCount(); @@ -229,6 +232,9 @@ void CodeController::handleMessage(MessageClearErrorCount* message) void CodeController::handleMessage(MessageFlushUpdates* message) { + MessageCodeViewExpandedInitialFiles* msgPtr = nullptr; + handleMessage(msgPtr); + showContents(message); } @@ -242,6 +248,21 @@ void CodeController::handleMessage(MessageFocusOut* message) getView()->defocusTokenIds(); } +void CodeController::handleMessage(MessageCodeViewExpandedInitialFiles* message) +{ + if (m_scrollToDefinition) + { + getView()->scrollToDefinition(); + m_scrollToDefinition = false; + } + + if (m_scrollToValue != -1) + { + getView()->scrollToValue(m_scrollToValue); + m_scrollToValue = -1; + } +} + void CodeController::handleMessage(MessageScrollToLine* message) { getView()->scrollToLine(message->filePath, message->line); @@ -266,7 +287,7 @@ void CodeController::handleMessage(MessageScrollCode* message) { if (message->isReplayed()) { - getView()->scrollToValue(message->value); + m_scrollToValue = message->value; } } diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index d6299e06..46ecd0e2 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -10,6 +10,7 @@ #include "utility/messaging/type/MessageActivateTokens.h" #include "utility/messaging/type/MessageChangeFileView.h" #include "utility/messaging/type/MessageClearErrorCount.h" +#include "utility/messaging/type/MessageCodeViewExpandedInitialFiles.h" #include "utility/messaging/type/MessageFlushUpdates.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" @@ -36,6 +37,7 @@ class CodeController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -57,6 +59,7 @@ private: virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageChangeFileView* message); virtual void handleMessage(MessageClearErrorCount* message); + virtual void handleMessage(MessageCodeViewExpandedInitialFiles* message); virtual void handleMessage(MessageFlushUpdates* message); virtual void handleMessage(MessageFocusIn* message); virtual void handleMessage(MessageFocusOut* message); @@ -91,6 +94,9 @@ private: StorageAccess* m_storageAccess; mutable std::shared_ptr m_collection; + + bool m_scrollToDefinition; + int m_scrollToValue; }; #endif // CODE_CONTROLLER_H diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index 96e864a3..1a01dd00 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -191,7 +191,7 @@ void GraphController::handleMessage(MessageShowReference* message) m_activeEdgeIds = std::vector(1, message->tokenId); setActiveAndVisibility(utility::concat(m_activeNodeIds, m_activeEdgeIds)); - buildGraph(message, false); + buildGraph(message, false, false); } GraphView* GraphController::getView() const diff --git a/src/lib/component/view/CodeView.h b/src/lib/component/view/CodeView.h index 621658c6..0e88ddd6 100644 --- a/src/lib/component/view/CodeView.h +++ b/src/lib/component/view/CodeView.h @@ -51,6 +51,7 @@ public: virtual void scrollToValue(int value) = 0; virtual void scrollToLine(const FilePath filePath, unsigned int line) = 0; + virtual void scrollToDefinition() = 0; private: CodeController* getController(); diff --git a/src/lib/utility/messaging/MessageListener.h b/src/lib/utility/messaging/MessageListener.h index 76e2d8c7..dff0f2a0 100644 --- a/src/lib/utility/messaging/MessageListener.h +++ b/src/lib/utility/messaging/MessageListener.h @@ -25,10 +25,10 @@ private: virtual void doHandleMessageBase(MessageBase* message) { - if (message->isLogged()) - { - LOG_INFO_STREAM_BARE(<< "handle " << message->str()); - } + // if (message->isLogged()) + // { + // LOG_INFO_STREAM_BARE(<< "handle " << message->str()); + // } handleMessage(dynamic_cast(message)); } diff --git a/src/lib/utility/messaging/type/MessageCodeViewExpandedInitialFiles.h b/src/lib/utility/messaging/type/MessageCodeViewExpandedInitialFiles.h new file mode 100644 index 00000000..51f244d0 --- /dev/null +++ b/src/lib/utility/messaging/type/MessageCodeViewExpandedInitialFiles.h @@ -0,0 +1,20 @@ +#ifndef MESSAGE_CODE_VIEW_EXPANDED_INITIAL_FILES_H +#define MESSAGE_CODE_VIEW_EXPANDED_INITIAL_FILES_H + +#include "utility/messaging/Message.h" + +class MessageCodeViewExpandedInitialFiles + : public Message +{ +public: + MessageCodeViewExpandedInitialFiles() + { + } + + static const std::string getStaticType() + { + return "MessageCodeViewExpandedInitialFiles"; + } +}; + +#endif // MESSAGE_CODE_VIEW_EXPANDED_INITIAL_FILES_H diff --git a/src/lib_gui/qt/element/QtCodeArea.cpp b/src/lib_gui/qt/element/QtCodeArea.cpp index 9c32f6ce..2b5fa563 100644 --- a/src/lib_gui/qt/element/QtCodeArea.cpp +++ b/src/lib_gui/qt/element/QtCodeArea.cpp @@ -275,6 +275,31 @@ uint QtCodeArea::getLineNumberForLocationId(Id locationId) const return 0; } +int QtCodeArea::getStartLineNumberOfFirstActiveScope() const +{ + int firstActiveLine = 0; + for (const Annotation& annotation : m_annotations) + { + if (annotation.locationType == LocationType::LOCATION_SCOPE && annotation.isActive) + { + if (firstActiveLine && firstActiveLine != annotation.startLine) + { + return annotation.startLine; + } + else + { + return getStartLineNumber(); + } + } + else if (annotation.isActive) + { + firstActiveLine = annotation.startLine; + } + } + + return 0; +} + QRectF QtCodeArea::getLineRectForLineNumber(uint lineNumber) const { if (lineNumber < getStartLineNumber()) diff --git a/src/lib_gui/qt/element/QtCodeArea.h b/src/lib_gui/qt/element/QtCodeArea.h index fbd4029e..ac2cafc2 100644 --- a/src/lib_gui/qt/element/QtCodeArea.h +++ b/src/lib_gui/qt/element/QtCodeArea.h @@ -83,6 +83,7 @@ public: void setIsActiveFile(bool isActiveFile); uint getLineNumberForLocationId(Id locationId) const; + int getStartLineNumberOfFirstActiveScope() const; QRectF getLineRectForLineNumber(uint lineNumber) const; std::string getCode() const; diff --git a/src/lib_gui/qt/element/QtCodeFile.cpp b/src/lib_gui/qt/element/QtCodeFile.cpp index 2912b33c..80630d01 100644 --- a/src/lib_gui/qt/element/QtCodeFile.cpp +++ b/src/lib_gui/qt/element/QtCodeFile.cpp @@ -273,6 +273,24 @@ QtCodeSnippet* QtCodeFile::getFileSnippet() const return m_fileSnippet.get(); } +std::pair QtCodeFile::getFirstSnippetWithActiveScope() const +{ + std::pair result(nullptr, 0); + + for (std::shared_ptr snippet : m_snippets) + { + int startLineNumber = snippet->getStartLineNumberOfFirstActiveScope(); + if (startLineNumber != 0) + { + result.first = snippet.get(); + result.second = startLineNumber; + break; + } + } + + return result; +} + bool QtCodeFile::isCollapsed() const { return m_locationFile != nullptr; diff --git a/src/lib_gui/qt/element/QtCodeFile.h b/src/lib_gui/qt/element/QtCodeFile.h index e21cdbb4..f5bb9b2a 100644 --- a/src/lib_gui/qt/element/QtCodeFile.h +++ b/src/lib_gui/qt/element/QtCodeFile.h @@ -42,6 +42,8 @@ public: QtCodeSnippet* getSnippetForLine(unsigned int line) const; QtCodeSnippet* getFileSnippet() const; + std::pair getFirstSnippetWithActiveScope() const; + bool isCollapsed() const; void requestContent() const; diff --git a/src/lib_gui/qt/element/QtCodeFileList.cpp b/src/lib_gui/qt/element/QtCodeFileList.cpp index aa2d3d32..b9311143 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.cpp +++ b/src/lib_gui/qt/element/QtCodeFileList.cpp @@ -127,3 +127,24 @@ QtCodeFile* QtCodeFileList::getFile(const FilePath filePath) return file; } + +std::pair QtCodeFileList::getFirstSnippetWithActiveScope() const +{ + std::pair result(nullptr, 0); + + for (std::shared_ptr filePtr : m_files) + { + if (filePtr->isCollapsed()) + { + continue; + } + + result = filePtr->getFirstSnippetWithActiveScope(); + if (result.first != nullptr) + { + break; + } + } + + return result; +} diff --git a/src/lib_gui/qt/element/QtCodeFileList.h b/src/lib_gui/qt/element/QtCodeFileList.h index 8ab88445..6ca8311c 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.h +++ b/src/lib_gui/qt/element/QtCodeFileList.h @@ -44,6 +44,7 @@ public: void onWindowFocus(); QtCodeFile* getFile(const FilePath filePath); + std::pair getFirstSnippetWithActiveScope() const; private: QtCodeSnippet* getFirstActiveSnippet() const; diff --git a/src/lib_gui/qt/element/QtCodeNavigator.cpp b/src/lib_gui/qt/element/QtCodeNavigator.cpp index fb781cde..d198c43c 100644 --- a/src/lib_gui/qt/element/QtCodeNavigator.cpp +++ b/src/lib_gui/qt/element/QtCodeNavigator.cpp @@ -12,6 +12,7 @@ #include "data/location/TokenLocationCollection.h" #include "data/location/TokenLocationFile.h" #include "utility/logging/logging.h" +#include "utility/messaging/type/MessageCodeViewExpandedInitialFiles.h" #include "utility/messaging/type/MessageScrollCode.h" #include "utility/messaging/type/MessageShowReference.h" @@ -82,8 +83,8 @@ QtCodeNavigator::QtCodeNavigator(QWidget* parent) m_scrollSpeedChangeListener.setScrollBar(m_scrollArea->verticalScrollBar()); connect(m_scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrolled(int))); - connect(this, SIGNAL(shouldScrollToSnippet(QtCodeSnippet*, uint)), - this, SLOT(scrollToSnippet(QtCodeSnippet*, uint)), Qt::QueuedConnection); + connect(this, SIGNAL(shouldScrollToSnippet(QtCodeSnippet*, uint, bool)), + this, SLOT(scrollToSnippet(QtCodeSnippet*, uint, bool)), Qt::QueuedConnection); } QtCodeNavigator::~QtCodeNavigator() @@ -357,6 +358,11 @@ void QtCodeNavigator::setupFiles() } } + if (filePathsToExpand.size()) + { + MessageCodeViewExpandedInitialFiles().dispatch(); + } + m_refIndex = 0; updateRefLabel(); } @@ -396,7 +402,7 @@ void QtCodeNavigator::showLocation(const FilePath& filePath, Id locationId, bool void QtCodeNavigator::scrollToValue(int value) { m_value = value; - QTimer::singleShot(100, this, SLOT(setValue())); + QTimer::singleShot(1000, this, SLOT(setValue())); } void QtCodeNavigator::scrollToLine(const FilePath& filePath, unsigned int line) @@ -417,7 +423,7 @@ void QtCodeNavigator::scrollToLine(const FilePath& filePath, unsigned int line) } else if (file->getFileSnippet()) { - emit shouldScrollToSnippet(file->getFileSnippet(), line); + emit shouldScrollToSnippet(file->getFileSnippet(), line, false); } else { @@ -454,20 +460,30 @@ void QtCodeNavigator::scrollToLocation(QtCodeFile* file, Id locationId, bool scr { if (locationId) { - emit shouldScrollToSnippet(snippet, snippet->getLineNumberForLocationId(locationId)); + emit shouldScrollToSnippet(snippet, snippet->getLineNumberForLocationId(locationId), false); } else { - emit shouldScrollToSnippet(snippet, 1); + emit shouldScrollToSnippet(snippet, 1, false); } } } +void QtCodeNavigator::scrollToDefinition() +{ + std::pair result = m_list->getFirstSnippetWithActiveScope(); + + if (result.first != nullptr) + { + emit shouldScrollToSnippet(result.first, result.second, true); + } +} + void QtCodeNavigator::scrollToSnippetIfRequested() { if (m_scrollToFile && m_scrollToLine) { - emit shouldScrollToSnippet(m_scrollToFile->getSnippetForLine(m_scrollToLine), m_scrollToLine); + emit shouldScrollToSnippet(m_scrollToFile->getSnippetForLine(m_scrollToLine), m_scrollToLine, false); } else if (m_scrollToFile && m_scrollToFile->hasSnippets()) { @@ -490,11 +506,11 @@ void QtCodeNavigator::scrolled(int value) MessageScrollCode(value).dispatch(); } -void QtCodeNavigator::scrollToSnippet(QtCodeSnippet* snippet, uint lineNumber) +void QtCodeNavigator::scrollToSnippet(QtCodeSnippet* snippet, uint lineNumber, bool onTop) { if (lineNumber) { - this->ensureWidgetVisibleAnimated(snippet, snippet->getLineRectForLineNumber(lineNumber)); + this->ensureWidgetVisibleAnimated(snippet, snippet->getLineRectForLineNumber(lineNumber), onTop); } } @@ -569,7 +585,7 @@ void QtCodeNavigator::updateRefLabel() m_nextButton->setEnabled(n > 1); } -void QtCodeNavigator::ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect) +void QtCodeNavigator::ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect, bool onTop) { QScrollArea* area = m_scrollArea; @@ -594,6 +610,15 @@ void QtCodeNavigator::ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF r QScrollBar* scrollBar = area->verticalScrollBar(); int value = focusRect.center().y() - visibleRect.center().y(); + if (onTop) + { + value = focusRect.top() - visibleRect.top(); + if (value < 50) + { + value = 0; + } + } + if (scrollBar && value != 0) { QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value"); diff --git a/src/lib_gui/qt/element/QtCodeNavigator.h b/src/lib_gui/qt/element/QtCodeNavigator.h index 49e029e3..3f8be038 100644 --- a/src/lib_gui/qt/element/QtCodeNavigator.h +++ b/src/lib_gui/qt/element/QtCodeNavigator.h @@ -72,16 +72,17 @@ public: void scrollToValue(int value); void scrollToLine(const FilePath& filePath, unsigned int line); void scrollToLocation(QtCodeFile* file, Id locationId, bool scrollTo); + void scrollToDefinition(); void scrollToSnippetIfRequested(); void requestScrollToLine(QtCodeFile* file, unsigned int line); signals: - void shouldScrollToSnippet(QtCodeSnippet* widget, uint lineNumber); + void shouldScrollToSnippet(QtCodeSnippet* widget, uint lineNumber, bool onTop); private slots: void scrolled(int value); - void scrollToSnippet(QtCodeSnippet* snippet, uint lineNumber); + void scrollToSnippet(QtCodeSnippet* snippet, uint lineNumber, bool onTop); void setValue(); void previousReference(); @@ -98,7 +99,7 @@ private: void showCurrentReference(); void updateRefLabel(); - void ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect); + void ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect, bool onTop); void handleMessage(MessageCodeReference* message); void handleMessage(MessageWindowFocus* message); diff --git a/src/lib_gui/qt/element/QtCodeSnippet.cpp b/src/lib_gui/qt/element/QtCodeSnippet.cpp index b95d7fc6..658df85b 100644 --- a/src/lib_gui/qt/element/QtCodeSnippet.cpp +++ b/src/lib_gui/qt/element/QtCodeSnippet.cpp @@ -160,6 +160,11 @@ uint QtCodeSnippet::getLineNumberForLocationId(Id locationId) const return m_codeArea->getLineNumberForLocationId(locationId); } +int QtCodeSnippet::getStartLineNumberOfFirstActiveScope() const +{ + return m_codeArea->getStartLineNumberOfFirstActiveScope(); +} + QRectF QtCodeSnippet::getLineRectForLineNumber(uint lineNumber) const { return m_codeArea->getLineRectForLineNumber(lineNumber); diff --git a/src/lib_gui/qt/element/QtCodeSnippet.h b/src/lib_gui/qt/element/QtCodeSnippet.h index 9b8414f6..a90ad4c7 100644 --- a/src/lib_gui/qt/element/QtCodeSnippet.h +++ b/src/lib_gui/qt/element/QtCodeSnippet.h @@ -43,6 +43,7 @@ public: void setIsActiveFile(bool isActiveFile); uint getLineNumberForLocationId(Id locationId) const; + int getStartLineNumberOfFirstActiveScope() const; QRectF getLineRectForLineNumber(uint lineNumber) const; std::string getCode() const; diff --git a/src/lib_gui/qt/view/QtCodeView.cpp b/src/lib_gui/qt/view/QtCodeView.cpp index a2c03737..adf8ac5c 100644 --- a/src/lib_gui/qt/view/QtCodeView.cpp +++ b/src/lib_gui/qt/view/QtCodeView.cpp @@ -124,6 +124,16 @@ void QtCodeView::scrollToLine(const FilePath filePath, unsigned int line) m_scrollToLineFunctor(filePath, line); } +void QtCodeView::scrollToDefinition() +{ + m_onQtThread( + [=]() + { + m_widget->scrollToDefinition(); + } + ); +} + void QtCodeView::doRefreshView() { setStyleSheet(); diff --git a/src/lib_gui/qt/view/QtCodeView.h b/src/lib_gui/qt/view/QtCodeView.h index 74013b47..aa120984 100644 --- a/src/lib_gui/qt/view/QtCodeView.h +++ b/src/lib_gui/qt/view/QtCodeView.h @@ -49,6 +49,7 @@ public: virtual void scrollToValue(int value); virtual void scrollToLine(const FilePath filePath, unsigned int line); + virtual void scrollToDefinition(); private: void doRefreshView(); @@ -89,6 +90,8 @@ private: QtThreadedFunctor m_scrollToValueFunctor; QtThreadedFunctor m_scrollToLineFunctor; + QtThreadedLambdaFunctor m_onQtThread; + QtCodeNavigator* m_widget; std::vector m_errorInfos;