diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 2b813798..b7b03a92 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -357,7 +357,6 @@ 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/MessageCreateBookmark.h utility/messaging/type/MessageCreateBookmarkCategory.h @@ -424,7 +423,7 @@ add_files( utility/messaging/MessageListenerBase.h utility/messaging/MessageQueue.cpp utility/messaging/MessageQueue.h - + utility/migration/Migration.h utility/migration/Migrator.h diff --git a/src/lib/component/controller/ActivationController.cpp b/src/lib/component/controller/ActivationController.cpp index 8a3665fc..fa8c6b0d 100644 --- a/src/lib/component/controller/ActivationController.cpp +++ b/src/lib/component/controller/ActivationController.cpp @@ -72,7 +72,7 @@ void ActivationController::handleMessage(MessageActivateFile* message) if (message->line > 0) { - MessageScrollToLine(message->filePath, message->line, true).dispatch(); + MessageScrollToLine(message->filePath, message->line).dispatch(); } } diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 4cb1763c..72095b78 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -18,9 +18,6 @@ CodeController::CodeController(StorageAccess* storageAccess) : m_storageAccess(storageAccess) - , m_scrollToDefinition(false) - , m_scrollToValue(-1) - , m_scrollToLine(0) { } @@ -94,10 +91,10 @@ void CodeController::handleMessage(MessageActivateAll* message) statsSnippet.code = ss.str(); - CodeView* view = getView(); - view->showCodeSnippets(std::vector(1, statsSnippet), std::vector(), true); - - showContents(message); + CodeView::CodeParams params; + params.clearSnippets = true; + params.showContents = !message->isReplayed(); + getView()->showCodeSnippets(std::vector(1, statsSnippet), params); } void CodeController::handleMessage(MessageActivateLocalSymbols* message) @@ -112,47 +109,47 @@ void CodeController::handleMessage(MessageActivateTokens* message) CodeView* view = getView(); - std::vector activeTokenIds = message->tokenIds; - if (!activeTokenIds.size()) + CodeView::CodeParams params; + params.activeTokenIds = message->tokenIds; + if (!params.activeTokenIds.size()) { view->clear(); return; } - if (!message->keepContent()) - { - view->clearCodeSnippets(); - } + params.clearSnippets = !message->keepContent(); + params.showContents = !message->isReplayed(); Id declarationId = 0; // 0 means that no token is found. if (!message->isAggregation) { - activeTokenIds = m_storageAccess->getActiveTokenIdsForId(activeTokenIds[0], &declarationId); + params.activeTokenIds = m_storageAccess->getActiveTokenIdsForId(params.activeTokenIds[0], &declarationId); } if (message->isEdge) { - std::shared_ptr collection = m_storageAccess->getSourceLocationsForTokenIds(activeTokenIds); - view->showActiveSnippet(activeTokenIds, collection, message->isLast()); + std::shared_ptr collection = + m_storageAccess->getSourceLocationsForTokenIds(params.activeTokenIds); + view->showActiveSnippet(params.activeTokenIds, collection, message->isLast()); + return; } - else if (message->keepContent()) + + if (message->keepContent()) { - view->showActiveTokenIds(activeTokenIds); - if (m_scrollToDefinition) - { - getView()->scrollToDefinition(true); - m_scrollToDefinition = false; - } + view->showActiveTokenIds(params.activeTokenIds); } else { - m_collection = m_storageAccess->getSourceLocationsForTokenIds(activeTokenIds); - view->showCodeSnippets( - getSnippetsForActiveSourceLocations(m_collection.get(), declarationId), - activeTokenIds, - !message->isReplayed() || message->isReplayCleared() - ); - m_scrollToDefinition = !message->isReplayed() || message->isReplayCleared(); + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION); + scrollParams.ignoreActiveReference = true; + view->scrollTo(scrollParams); + + m_collection = m_storageAccess->getSourceLocationsForTokenIds(params.activeTokenIds); + + std::vector snippets = getSnippetsForActiveSourceLocations(m_collection.get(), declarationId); + expandVisibleSnippets(&snippets); + + view->showCodeSnippets(snippets, params); size_t fileCount = m_collection->getSourceLocationFileCount(); size_t referenceCount = m_collection->getSourceLocationCount(); @@ -177,27 +174,23 @@ void CodeController::handleMessage(MessageActivateTokens* message) MessageStatus(ss.str()).dispatch(); } - - showContents(message); } void CodeController::handleMessage(MessageActivateTrailEdge* message) { TRACE("trail edge activate"); - CodeView* view = getView(); - view->clearCodeSnippets(); + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION); + getView()->scrollTo(scrollParams); - std::vector activeTokenIds = { message->tokenId }; - m_collection = m_storageAccess->getSourceLocationsForTokenIds(activeTokenIds); + CodeView::CodeParams params; + params.clearSnippets = true; + params.showContents = !message->isReplayed(); + params.activeTokenIds.push_back(message->tokenId); - view->showCodeSnippets( - getSnippetsForActiveSourceLocations(m_collection.get(), 0), - activeTokenIds, - !message->isReplayed() || message->isReplayCleared() - ); + m_collection = m_storageAccess->getSourceLocationsForTokenIds(params.activeTokenIds); - showContents(message); + getView()->showCodeSnippets(getSnippetsForActiveSourceLocations(m_collection.get(), 0), params); } void CodeController::handleMessage(MessageChangeFileView* message) @@ -212,87 +205,38 @@ void CodeController::handleMessage(MessageChangeFileView* message) CodeView* view = getView(); bool inListMode = view->isInListMode(); - MessageChangeFileView::FileState state = message->state; - if (state == MessageChangeFileView::FILE_DEFAULT_FOR_MODE) - { - state = inListMode ? MessageChangeFileView::FILE_SNIPPETS : MessageChangeFileView::FILE_MAXIMIZED; - } - - switch (state) + CodeView::FileState state; + switch (message->state) { case MessageChangeFileView::FILE_MINIMIZED: - view->setFileState(message->filePath, CodeView::FILE_MINIMIZED); + state = CodeView::FILE_MINIMIZED; break; case MessageChangeFileView::FILE_SNIPPETS: - if (message->needsData && inListMode) - { - std::shared_ptr file = m_collection->getSourceLocationFileByPath(message->filePath); - if (!file) - { - return; - } - - if (message->showErrors) - { - file->setIsWhole(false); - } - - view->addCodeSnippets(getSnippetsForFile(file, !message->showErrors), false); - } - view->setFileState(message->filePath, CodeView::FILE_SNIPPETS); + state = CodeView::FILE_SNIPPETS; break; case MessageChangeFileView::FILE_MAXIMIZED: - if (message->needsData) - { - CodeSnippetParams params; - params.startLineNumber = 1; - params.refCount = -1; - - std::shared_ptr textAccess = m_storageAccess->getFileContent(message->filePath); - params.code = textAccess->getText(); - - params.modificationTime = m_storageAccess->getFileInfoForFilePath(message->filePath).lastWriteTime; - - if (message->showErrors) - { - params.locationFile = m_collection->getSourceLocationFileByPath(message->filePath); - if (!params.locationFile) - { - return; - } - params.locationFile->setIsWhole(true); - } - else - { - std::shared_ptr file = - m_storageAccess->getSourceLocationsForFile(message->filePath); - - SourceLocationFile* activeLocations = m_collection->getSourceLocationFileByPath(message->filePath).get(); - if (activeLocations) - { - activeLocations->forEachSourceLocation( - [&file](SourceLocation* location) - { - file->addSourceLocationCopy(location); - } - ); - } - - params.locationFile = file; - } - - getView()->addCodeSnippets(std::vector(1, params), false); - } - - view->setFileState(message->filePath, CodeView::FILE_MAXIMIZED); + state = CodeView::FILE_MAXIMIZED; break; - default: + + case MessageChangeFileView::FILE_DEFAULT_FOR_MODE: + state = inListMode ? CodeView::FILE_SNIPPETS : CodeView::FILE_MAXIMIZED; break; } - showContents(message); + if (message->needsData) + { + CodeView::CodeParams params; + view->showCodeSnippets(getSnippetsForFileWithState(message->filePath, state, !message->showErrors), params); + } + + view->setFileState(message->filePath, state); + + if (!message->isReplayed()) + { + view->showContents(); + } } void CodeController::handleMessage(MessageClearErrorCount* message) @@ -307,16 +251,16 @@ void CodeController::handleMessage(MessageDeactivateEdge* message) { if (message->scrollToDefinition) { - m_scrollToDefinition = true; + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION); + scrollParams.animated = true; + scrollParams.ignoreActiveReference = true; + getView()->scrollTo(scrollParams); } } void CodeController::handleMessage(MessageFlushUpdates* message) { - MessageCodeViewExpandedInitialFiles* msgPtr = nullptr; - handleMessage(msgPtr); - - showContents(message); + getView()->showContents(); } void CodeController::handleMessage(MessageFocusIn* message) @@ -329,54 +273,28 @@ void CodeController::handleMessage(MessageFocusOut* message) getView()->defocusTokenIds(); } -void CodeController::handleMessage(MessageCodeViewExpandedInitialFiles* message) -{ - if (m_scrollToDefinition || (message && message->scrollToDefinition)) - { - getView()->scrollToDefinition(false); - m_scrollToDefinition = false; - } - - if (m_scrollToValue != -1) - { - getView()->scrollToValue(m_scrollToValue, m_scrollInListMode); - m_scrollToValue = -1; - } - - if (m_scrollToLine) - { - getView()->scrollToLine(m_scrollToFilePath, m_scrollToLine); - m_scrollToLine = 0; - } -} - void CodeController::handleMessage(MessageScrollToLine* message) { - m_scrollToFilePath = message->filePath; - m_scrollToLine = message->line; + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_LINE); + scrollParams.filePath = message->filePath; + scrollParams.line = message->line; + getView()->scrollTo(scrollParams); - if (message->isModified) - { - MessageStatus( - "Showing source location: " + message->filePath.str() - + " : " + std::to_string(message->line) + ". The file was modified, please refresh.", - true - ).dispatch(); - } - else - { - MessageStatus( - "Showing source location: " + message->filePath.str() + " : " + std::to_string(message->line) - ).dispatch(); - } + MessageStatus( + "Showing source location: " + message->filePath.str() + + " : " + std::to_string(message->line) + ". The file was modified, please refresh.", + true + ).dispatch(); } void CodeController::handleMessage(MessageScrollCode* message) { if (message->isReplayed()) { - m_scrollToValue = message->value; - m_scrollInListMode = message->inListMode; + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_VALUE); + scrollParams.value = message->value; + scrollParams.inListMode = message->inListMode; + getView()->scrollTo(scrollParams); } } @@ -387,23 +305,28 @@ void CodeController::handleMessage(MessageShowErrors* message) CodeView* view = getView(); if (!view->showsErrors() || !message->errorId) { + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION); + view->scrollTo(scrollParams); + std::vector errors; m_collection = m_storageAccess->getErrorSourceLocationsLimited(&errors); std::vector snippets = getSnippetsForCollection(m_collection); std::sort(snippets.begin(), snippets.end(), CodeSnippetParams::sortById); - view->clear(); - view->setErrorInfos(errors); - view->showCodeSnippets( - snippets, std::vector(), !message->errorId && (!message->isReplayed() || message->isReplayCleared())); + expandVisibleSnippets(&snippets); - showContents(message); + CodeView::CodeParams params; + params.clearSnippets = true; + params.errorInfos = errors; + params.showContents = !message->isReplayed(); + + view->showCodeSnippets(snippets, params); } if (message->errorId) { - view->showActiveSnippet(std::vector(1, message->errorId), m_collection, true); + view->showActiveSnippet(std::vector(1, message->errorId), m_collection, message->isLast()); } } @@ -411,14 +334,18 @@ void CodeController::handleMessage(MessageSearchFullText* message) { TRACE("code fulltext"); - CodeView* view = getView(); - view->clear(); - m_collection = m_storageAccess->getFullTextSearchLocations(message->searchTerm, message->caseSensitive); - view->showCodeSnippets( - getSnippetsForCollection(m_collection, true), std::vector(), !message->isReplayed() || message->isReplayCleared()); - showContents(message); + CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION); + getView()->scrollTo(scrollParams); + + std::vector snippets = getSnippetsForCollection(m_collection, true); + expandVisibleSnippets(&snippets); + + CodeView::CodeParams params; + params.clearSnippets = true; + params.showContents = !message->isReplayed(); + getView()->showCodeSnippets(snippets, params); } void CodeController::handleMessage(MessageShowScope* message) @@ -443,32 +370,23 @@ void CodeController::handleMessage(MessageShowScope* message) return; } + snippets[0].insertSnippet = true; + if (message->showErrors) { snippets[0].locationFile = m_collection->getSourceLocationFileByPath(snippets[0].locationFile->getFilePath()); } else { - SourceLocationFile* activeLocations = - m_collection->getSourceLocationFileByPath(snippets[0].locationFile->getFilePath()).get(); - if (activeLocations) - { - std::shared_ptr file = snippets[0].locationFile; - activeLocations->forEachSourceLocation( - [&file](SourceLocation* location) - { - file->addSourceLocationCopy(location); - } - ); - } + addActiveSourceLocations(snippets[0].locationFile); } - getView()->addCodeSnippets(snippets, true); - - showContents(message); + CodeView::CodeParams params; + params.showContents = !message->isReplayed(); + getView()->showCodeSnippets(snippets, params); } -CodeView* CodeController::getView() +CodeView* CodeController::getView() const { return Controller::getView(); } @@ -480,14 +398,103 @@ void CodeController::clear() m_collection.reset(); } -void CodeController::showContents(MessageBase* message) +void CodeController::expandVisibleSnippets(std::vector* snippets) const { - if (!message->isReplayed()) + bool inListMode = getView()->isInListMode(); + + size_t filesToExpand = inListMode ? std::min(int(snippets->size()), 3) : 1; + CodeView::FileState state = inListMode ? CodeView::FILE_SNIPPETS : CodeView::FILE_MAXIMIZED; + + for (size_t i = 0; i < filesToExpand; i++) { - getView()->showContents(); + CodeSnippetParams& oldSnippet = snippets->at(i); + + if (!inListMode && getView()->hasSingleFileCached(oldSnippet.locationFile->getFilePath())) + { + continue; + } + + std::vector newSnippets = + getSnippetsForFileWithState(oldSnippet.locationFile->getFilePath(), state, true); + if (!newSnippets.size()) + { + continue; + } + + for (CodeSnippetParams newSnippet : newSnippets) + { + newSnippet.isDeclaration = oldSnippet.isDeclaration; + newSnippet.isDefinition = oldSnippet.isDefinition; + + newSnippet.isCollapsed = false; + } + + snippets->insert(snippets->end(), newSnippets.begin(), newSnippets.end()); } } +std::vector CodeController::getSnippetsForFileWithState( + const FilePath& filePath, CodeView::FileState state, bool addSourceLocations) const +{ + TRACE(); + + std::vector snippets; + + switch (state) + { + case CodeView::FILE_SNIPPETS: + { + std::shared_ptr file = m_collection->getSourceLocationFileByPath(filePath); + if (!file) + { + return snippets; + } + + if (!addSourceLocations) + { + file->setIsWhole(false); + } + + snippets = getSnippetsForFile(file, addSourceLocations); + } + break; + + case CodeView::FILE_MAXIMIZED: + { + CodeSnippetParams params; + params.startLineNumber = 1; + params.refCount = -1; + + std::shared_ptr textAccess = m_storageAccess->getFileContent(filePath); + params.code = textAccess->getText(); + + params.modificationTime = m_storageAccess->getFileInfoForFilePath(filePath).lastWriteTime; + + if (!addSourceLocations) + { + params.locationFile = m_collection->getSourceLocationFileByPath(filePath); + if (!params.locationFile) + { + break; + } + params.locationFile->setIsWhole(true); + } + else + { + params.locationFile = m_storageAccess->getSourceLocationsForFile(filePath); + addActiveSourceLocations(params.locationFile); + } + + snippets.push_back(params); + } + break; + default: + break; + } + + return snippets; +} + std::vector CodeController::getSnippetsForActiveSourceLocations( const SourceLocationCollection* collection, Id declarationId ) const { @@ -857,3 +864,17 @@ void CodeController::addModificationTimes(std::vector& snippe snippet.modificationTime = fileInfoMap[snippet.locationFile->getFilePath()].lastWriteTime; } } + +void CodeController::addActiveSourceLocations(std::shared_ptr locationFile) const +{ + SourceLocationFile* activeLocations = m_collection->getSourceLocationFileByPath(locationFile->getFilePath()).get(); + if (activeLocations) + { + activeLocations->forEachSourceLocation( + [&locationFile](SourceLocation* location) + { + locationFile->addSourceLocationCopy(location); + } + ); + } +} diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index f49ebb62..b1475c36 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -12,7 +12,6 @@ #include "utility/messaging/type/MessageActivateTrailEdge.h" #include "utility/messaging/type/MessageChangeFileView.h" #include "utility/messaging/type/MessageClearErrorCount.h" -#include "utility/messaging/type/MessageCodeViewExpandedInitialFiles.h" #include "utility/messaging/type/MessageDeactivateEdge.h" #include "utility/messaging/type/MessageFlushUpdates.h" #include "utility/messaging/type/MessageFocusIn.h" @@ -41,7 +40,6 @@ class CodeController , public MessageListener , public MessageListener , public MessageListener - , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -65,7 +63,6 @@ private: virtual void handleMessage(MessageActivateTrailEdge* message); virtual void handleMessage(MessageChangeFileView* message); virtual void handleMessage(MessageClearErrorCount* message); - virtual void handleMessage(MessageCodeViewExpandedInitialFiles* message); virtual void handleMessage(MessageDeactivateEdge* message); virtual void handleMessage(MessageFlushUpdates* message); virtual void handleMessage(MessageFocusIn* message); @@ -76,11 +73,14 @@ private: virtual void handleMessage(MessageShowErrors* message); virtual void handleMessage(MessageShowScope* message); - CodeView* getView(); + CodeView* getView() const; virtual void clear(); - void showContents(MessageBase* message); + void expandVisibleSnippets(std::vector* snippets) const; + + std::vector getSnippetsForFileWithState( + const FilePath& filePath, CodeView::FileState state, bool addSourceLocations) const; std::vector getSnippetsForActiveSourceLocations( const SourceLocationCollection* collection, Id declarationId) const; @@ -98,15 +98,10 @@ private: std::vector getProjectDescription(SourceLocationFile* locationFile) const; void addModificationTimes(std::vector& snippets) const; + void addActiveSourceLocations(std::shared_ptr locationFile) const; StorageAccess* m_storageAccess; mutable std::shared_ptr m_collection; - - bool m_scrollToDefinition; - int m_scrollToValue; - bool m_scrollInListMode; - FilePath m_scrollToFilePath; - size_t m_scrollToLine; }; #endif // CODE_CONTROLLER_H diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index addc7752..7bc3e15c 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -369,7 +369,7 @@ void GraphController::handleMessage(MessageShowErrors* message) void GraphController::handleMessage(MessageShowReference* message) { - if (!message->tokenId || !message->animated) + if (!message->tokenId || !message->fromUser) { return; } diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 8a41d1a3..f2781321 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -152,7 +152,6 @@ void UndoRedoController::handleMessage(MessageFinishedParsing* message) msg->isFromSearch = false; } - command.message->setIsReplayCleared(true); newList.insert(newList.end(), command); } } @@ -469,7 +468,6 @@ void UndoRedoController::replayCommand(std::list::iterator it) } m->dispatch(); - m->setIsReplayCleared(false); } void UndoRedoController::processCommand(Command command) diff --git a/src/lib/component/view/CodeView.h b/src/lib/component/view/CodeView.h index e9b2123c..bc49b1af 100644 --- a/src/lib/component/view/CodeView.h +++ b/src/lib/component/view/CodeView.h @@ -23,21 +23,60 @@ public: FILE_MAXIMIZED }; + struct CodeParams + { + CodeParams() + : clearSnippets(false) + , showContents(false) + {} + + bool clearSnippets; + bool showContents; + std::vector activeTokenIds; + std::vector errorInfos; + }; + + struct ScrollParams + { + enum ScrollType + { + SCROLL_NONE, + SCROLL_TO_DEFINITION, + SCROLL_TO_LINE, + SCROLL_TO_VALUE + } type; + + ScrollParams(ScrollType type = SCROLL_NONE) + : type(type) + , line(0) + , value(0) + , animated(false) + , ignoreActiveReference(false) + , inListMode(false) + {} + + FilePath filePath; + size_t line; + + size_t value; + + bool animated; + bool ignoreActiveReference; + bool inListMode; + }; + CodeView(ViewLayout* viewLayout); virtual ~CodeView(); virtual std::string getName() const; virtual void clear() = 0; - virtual void clearCodeSnippets() = 0; - virtual void setErrorInfos(const std::vector& errorInfos) = 0; + virtual void showCodeSnippets(const std::vector& snippets, const CodeParams params) = 0; + virtual void scrollTo(const ScrollParams params) = 0; + virtual bool showsErrors() const = 0; - virtual void showCodeSnippets( - const std::vector& snippets, const std::vector& activeTokenIds, bool setupFiles) = 0; - virtual void addCodeSnippets(const std::vector& snippets, bool insert) = 0; - virtual void setFileState(const FilePath filePath, FileState state) = 0; virtual void showActiveSnippet( @@ -50,11 +89,8 @@ public: virtual void showContents() = 0; - virtual void scrollToValue(int value, bool inListMode) = 0; - virtual void scrollToLine(const FilePath filePath, unsigned int line) = 0; - virtual void scrollToDefinition(bool ignoreActiveReference) = 0; - virtual bool isInListMode() const = 0; + virtual bool hasSingleFileCached(const FilePath& filePath) const = 0; private: CodeController* getController(); diff --git a/src/lib/component/view/helper/CodeSnippetParams.cpp b/src/lib/component/view/helper/CodeSnippetParams.cpp index f3dfe4a7..535beeb0 100644 --- a/src/lib/component/view/helper/CodeSnippetParams.cpp +++ b/src/lib/component/view/helper/CodeSnippetParams.cpp @@ -7,11 +7,11 @@ CodeSnippetParams::CodeSnippetParams() , endLineNumber(0) , titleId(0) , footerId(0) - , locationFile() , refCount(0) , isCollapsed(false) , isDeclaration(false) , isDefinition(false) + , insertSnippet(false) , reduced(false) { } diff --git a/src/lib/component/view/helper/CodeSnippetParams.h b/src/lib/component/view/helper/CodeSnippetParams.h index 6370e19f..188df5ab 100644 --- a/src/lib/component/view/helper/CodeSnippetParams.h +++ b/src/lib/component/view/helper/CodeSnippetParams.h @@ -36,6 +36,7 @@ struct CodeSnippetParams bool isDeclaration; bool isDefinition; + bool insertSnippet; bool reduced; }; diff --git a/src/lib/utility/messaging/MessageBase.h b/src/lib/utility/messaging/MessageBase.h index 4b1b991c..3e43356b 100644 --- a/src/lib/utility/messaging/MessageBase.h +++ b/src/lib/utility/messaging/MessageBase.h @@ -10,7 +10,6 @@ public: MessageBase() : m_isParallel(false) , m_isReplayed(false) - , m_isReplayCleared(false) , m_sendAsTask(true) , m_keepContent(false) , m_isLast(true) @@ -55,16 +54,6 @@ public: m_isReplayed = isReplayed; } - bool isReplayCleared() const - { - return m_isReplayCleared; - } - - void setIsReplayCleared(bool isReplayCleared) - { - m_isReplayCleared = isReplayCleared; - } - bool isLast() const { return m_isLast; @@ -107,9 +96,7 @@ public: private: bool m_isParallel; - bool m_isReplayed; - bool m_isReplayCleared; bool m_sendAsTask; bool m_keepContent; diff --git a/src/lib/utility/messaging/type/MessageCodeViewExpandedInitialFiles.h b/src/lib/utility/messaging/type/MessageCodeViewExpandedInitialFiles.h deleted file mode 100644 index d2d11dc3..00000000 --- a/src/lib/utility/messaging/type/MessageCodeViewExpandedInitialFiles.h +++ /dev/null @@ -1,23 +0,0 @@ -#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(bool scrollToDefinition) - : scrollToDefinition(scrollToDefinition) - { - } - - static const std::string getStaticType() - { - return "MessageCodeViewExpandedInitialFiles"; - } - - bool scrollToDefinition; -}; - -#endif // MESSAGE_CODE_VIEW_EXPANDED_INITIAL_FILES_H diff --git a/src/lib/utility/messaging/type/MessageScrollToLine.h b/src/lib/utility/messaging/type/MessageScrollToLine.h index b2e0f8d8..9161c595 100644 --- a/src/lib/utility/messaging/type/MessageScrollToLine.h +++ b/src/lib/utility/messaging/type/MessageScrollToLine.h @@ -1,17 +1,16 @@ -#ifndef MESSAGE_SCROLL_TO_LINE_h -#define MESSAGE_SCROLL_TO_LINE_h +#ifndef MESSAGE_SCROLL_TO_LINE_H +#define MESSAGE_SCROLL_TO_LINE_H -#include "utility/messaging/Message.h" #include "utility/file/FilePath.h" +#include "utility/messaging/Message.h" class MessageScrollToLine : public Message { public: - MessageScrollToLine(const FilePath& filePath, unsigned int line, bool isModified = false) + MessageScrollToLine(const FilePath& filePath, size_t line) : filePath(filePath) , line(line) - , isModified(isModified) { } @@ -21,8 +20,7 @@ public: } const FilePath filePath; - unsigned int line; - bool isModified; + size_t line; }; -#endif // MESSAGE_SCROLL_TO_LINE_h +#endif // MESSAGE_SCROLL_TO_LINE_H diff --git a/src/lib/utility/messaging/type/MessageShowReference.h b/src/lib/utility/messaging/type/MessageShowReference.h index 1430d8c9..7bfca669 100644 --- a/src/lib/utility/messaging/type/MessageShowReference.h +++ b/src/lib/utility/messaging/type/MessageShowReference.h @@ -8,11 +8,11 @@ class MessageShowReference : public Message { public: - MessageShowReference(size_t refIndex, Id tokenId, Id locationId, bool animated) + MessageShowReference(size_t refIndex, Id tokenId, Id locationId, bool fromUser) : refIndex(refIndex) , tokenId(tokenId) , locationId(locationId) - , animated(animated) + , fromUser(fromUser) { } @@ -29,7 +29,7 @@ public: const size_t refIndex; const Id tokenId; const Id locationId; - const bool animated; + const bool fromUser; }; #endif // MESSAGE_SHOW_REFERENCE_H diff --git a/src/lib_gui/qt/element/QtCodeArea.cpp b/src/lib_gui/qt/element/QtCodeArea.cpp index 50c94b90..8d9ed283 100644 --- a/src/lib_gui/qt/element/QtCodeArea.cpp +++ b/src/lib_gui/qt/element/QtCodeArea.cpp @@ -153,7 +153,6 @@ QtCodeArea::QtCodeArea( m_highlighter->highlightDocument(); createAnnotations(locationFile); - annotateText(); } QtCodeArea::~QtCodeArea() @@ -294,39 +293,38 @@ uint QtCodeArea::getLineNumberForLocationId(Id locationId) const return 0; } -uint QtCodeArea::getStartLineNumberOfFirstActiveLocationOfTokenId(Id tokenId) const +std::pair QtCodeArea::getLineNumbersForLocationId(Id locationId) const { - int firstActiveLine = 0; for (const Annotation& annotation : m_annotations) { - if (annotation.locationType == LocationType::LOCATION_TOKEN && annotation.isActive) + if (annotation.locationId == locationId) { - if (annotation.tokenIds.find(tokenId) != annotation.tokenIds.end()) - { - if (!firstActiveLine || firstActiveLine == annotation.startLine) - { - return getStartLineNumber(); - } - else - { - return annotation.startLine; - } - } - else - { - firstActiveLine = annotation.startLine; - } + return std::pair(annotation.startLine, annotation.endLine); + } + } + + return std::pair(0, 0); +} + +Id QtCodeArea::getLocationIdOfFirstActiveLocation(Id tokenId) const +{ + for (const Annotation& annotation : m_annotations) + { + if (annotation.locationType == LocationType::LOCATION_TOKEN && annotation.isActive && + annotation.tokenIds.find(tokenId) != annotation.tokenIds.end()) + { + return annotation.locationId; } } return 0; } -Id QtCodeArea::getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) const +Id QtCodeArea::getLocationIdOfFirstActiveScopeLocation(Id tokenId) const { for (const Annotation& annotation : m_annotations) { - if (annotation.locationType == LocationType::LOCATION_TOKEN && annotation.isActive && + if (annotation.locationType == LocationType::LOCATION_SCOPE && annotation.isActive && annotation.tokenIds.find(tokenId) != annotation.tokenIds.end()) { return annotation.locationId; diff --git a/src/lib_gui/qt/element/QtCodeArea.h b/src/lib_gui/qt/element/QtCodeArea.h index ab6d3ebc..3dc659c2 100644 --- a/src/lib_gui/qt/element/QtCodeArea.h +++ b/src/lib_gui/qt/element/QtCodeArea.h @@ -85,8 +85,11 @@ public: void setIsActiveFile(bool isActiveFile); uint getLineNumberForLocationId(Id locationId) const; - uint getStartLineNumberOfFirstActiveLocationOfTokenId(Id tokenId) const; - Id getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) const; + std::pair getLineNumbersForLocationId(Id locationId) const; + + Id getLocationIdOfFirstActiveLocation(Id tokenId) const; + Id getLocationIdOfFirstActiveScopeLocation(Id tokenId) const; + uint getActiveLocationCount() const; QRectF getLineRectForLineNumber(uint lineNumber) const; diff --git a/src/lib_gui/qt/element/QtCodeFile.cpp b/src/lib_gui/qt/element/QtCodeFile.cpp index 8fe1eff8..e77667e9 100644 --- a/src/lib_gui/qt/element/QtCodeFile.cpp +++ b/src/lib_gui/qt/element/QtCodeFile.cpp @@ -226,17 +226,17 @@ QtCodeSnippet* QtCodeFile::getFileSnippet() const return m_fileSnippet.get(); } -std::pair QtCodeFile::getFirstSnippetWithActiveLocation(Id tokenId) const +std::pair QtCodeFile::getFirstSnippetWithActiveLocationId(Id tokenId) const { - std::pair result(nullptr, 0); + std::pair result(nullptr, 0); for (std::shared_ptr snippet : m_snippets) { - uint startLineNumber = snippet->getStartLineNumberOfFirstActiveLocationOfTokenId(tokenId); - if (startLineNumber != 0) + Id locationId = snippet->getFirstActiveLocationId(tokenId); + if (locationId != 0) { result.first = snippet.get(); - result.second = startLineNumber; + result.second = locationId; break; } } @@ -249,7 +249,7 @@ bool QtCodeFile::isCollapsed() const return m_isCollapsed; } -void QtCodeFile::requestContent(bool isFirstInList) +void QtCodeFile::requestContent() { if (!isCollapsed() || m_contentRequested) { @@ -260,12 +260,7 @@ void QtCodeFile::requestContent(bool isFirstInList) m_contentRequested = true; MessageChangeFileView::FileState state = - isFirstInList ? MessageChangeFileView::FILE_DEFAULT_FOR_MODE : MessageChangeFileView::FILE_SNIPPETS; - - if (m_isWholeFile) - { - state = MessageChangeFileView::FILE_MAXIMIZED; - } + m_isWholeFile ? MessageChangeFileView::FILE_MAXIMIZED : MessageChangeFileView::FILE_SNIPPETS; MessageChangeFileView(m_filePath, state, isCollapsed(), m_navigator->hasErrors()).dispatch(); } diff --git a/src/lib_gui/qt/element/QtCodeFile.h b/src/lib_gui/qt/element/QtCodeFile.h index 14970e6b..0af62f94 100644 --- a/src/lib_gui/qt/element/QtCodeFile.h +++ b/src/lib_gui/qt/element/QtCodeFile.h @@ -39,11 +39,11 @@ public: QtCodeSnippet* getSnippetForLine(unsigned int line) const; QtCodeSnippet* getFileSnippet() const; - std::pair getFirstSnippetWithActiveLocation(Id tokenId) const; + std::pair getFirstSnippetWithActiveLocationId(Id tokenId) const; bool isCollapsed() const; - void requestContent(bool isFirstInList = false); + void requestContent(); void updateContent(); void setWholeFile(bool isWholeFile, int refCount); diff --git a/src/lib_gui/qt/element/QtCodeFileList.cpp b/src/lib_gui/qt/element/QtCodeFileList.cpp index 2113d145..696e212c 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.cpp +++ b/src/lib_gui/qt/element/QtCodeFileList.cpp @@ -83,14 +83,12 @@ QScrollArea* QtCodeFileList::getScrollArea() return this; } -void QtCodeFileList::addCodeSnippet( - const CodeSnippetParams& params, - bool insert -){ +void QtCodeFileList::addCodeSnippet(const CodeSnippetParams& params) +{ QtCodeFile* file = getFile(params.locationFile->getFilePath()); QtCodeSnippet* snippet = nullptr; - if (insert) + if (params.insertSnippet) { snippet = file->insertCodeSnippet(params); } @@ -103,9 +101,9 @@ void QtCodeFileList::addCodeSnippet( file->setIsComplete(params.locationFile->isComplete()); } -void QtCodeFileList::requestFileContent(const FilePath& filePath, bool isFirstInList) +void QtCodeFileList::requestFileContent(const FilePath& filePath) { - getFile(filePath)->requestContent(isFirstInList); + getFile(filePath)->requestContent(); } bool QtCodeFileList::requestScroll(const FilePath& filePath, uint lineNumber, Id locationId, bool animated, bool onTop) @@ -147,11 +145,19 @@ bool QtCodeFileList::requestScroll(const FilePath& filePath, uint lineNumber, Id file->setSnippets(); } + uint endLineNumber = 0; if (!lineNumber) { if (locationId) { - lineNumber = snippet->getLineNumberForLocationId(locationId); + std::pair lineNumbers = snippet->getLineNumbersForLocationId(locationId); + + lineNumber = lineNumbers.first; + + if (lineNumbers.first != lineNumbers.second) + { + endLineNumber = lineNumbers.second; + } } else { @@ -159,7 +165,13 @@ bool QtCodeFileList::requestScroll(const FilePath& filePath, uint lineNumber, Id } } - ensureWidgetVisibleAnimated(m_filesArea, snippet, snippet->getLineRectForLineNumber(lineNumber), animated, onTop); + QRectF lineRect = snippet->getLineRectForLineNumber(lineNumber); + if (endLineNumber) + { + lineRect |= snippet->getLineRectForLineNumber(endLineNumber); + } + + ensureWidgetVisibleAnimated(m_filesArea, snippet, lineRect, animated, onTop); return true; } @@ -203,9 +215,9 @@ void QtCodeFileList::setFileMaximized(const FilePath path) getFile(path)->setMaximized(); } -std::pair QtCodeFileList::getFirstSnippetWithActiveLocation(Id tokenId) const +std::pair QtCodeFileList::getFirstSnippetWithActiveLocationId(Id tokenId) const { - std::pair result(nullptr, 0); + std::pair result(nullptr, 0); for (std::shared_ptr filePtr : m_files) { @@ -214,7 +226,7 @@ std::pair QtCodeFileList::getFirstSnippetWithActiveLocatio continue; } - result = filePtr->getFirstSnippetWithActiveLocation(tokenId); + result = filePtr->getFirstSnippetWithActiveLocationId(tokenId); if (result.first != nullptr) { break; diff --git a/src/lib_gui/qt/element/QtCodeFileList.h b/src/lib_gui/qt/element/QtCodeFileList.h index f08bc554..7d074544 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.h +++ b/src/lib_gui/qt/element/QtCodeFileList.h @@ -33,9 +33,9 @@ public: // QtCodeNaviatebale implementation virtual QScrollArea* getScrollArea(); - virtual void addCodeSnippet(const CodeSnippetParams& params, bool insert = false); + virtual void addCodeSnippet(const CodeSnippetParams& params); - void requestFileContent(const FilePath& filePath, bool isFirstInList = false); + virtual void requestFileContent(const FilePath& filePath); virtual bool requestScroll(const FilePath& filePath, uint lineNumber, Id locationId, bool animated, bool onTop); virtual void updateFiles(); @@ -47,7 +47,7 @@ public: void setFileSnippets(const FilePath path); void setFileMaximized(const FilePath path); - std::pair getFirstSnippetWithActiveLocation(Id tokenId) const; + std::pair getFirstSnippetWithActiveLocationId(Id tokenId) const; private: QtCodeNavigator* m_navigator; diff --git a/src/lib_gui/qt/element/QtCodeFileSingle.cpp b/src/lib_gui/qt/element/QtCodeFileSingle.cpp index 625428d5..61556b04 100644 --- a/src/lib_gui/qt/element/QtCodeFileSingle.cpp +++ b/src/lib_gui/qt/element/QtCodeFileSingle.cpp @@ -20,6 +20,7 @@ QtCodeFileSingle::QtCodeFileSingle(QtCodeNavigator* navigator, QWidget* parent) : m_navigator(navigator) , m_area(nullptr) , m_contentRequested(false) + , m_scrollRequested(false) { setObjectName("code_container"); @@ -83,7 +84,7 @@ void QtCodeFileSingle::clearCache() m_filePaths.clear(); } -void QtCodeFileSingle::addCodeSnippet(const CodeSnippetParams& params, bool insert) +void QtCodeFileSingle::addCodeSnippet(const CodeSnippetParams& params) { if (!params.locationFile->isWhole()) { @@ -163,11 +164,24 @@ bool QtCodeFileSingle::requestScroll(const FilePath& filePath, uint lineNumber, return false; } + if (!m_scrollRequested) + { + animated = false; + } + + uint endLineNumber = 0; if (!lineNumber) { if (locationId) { - lineNumber = m_area->getLineNumberForLocationId(locationId); + std::pair lineNumbers = m_area->getLineNumbersForLocationId(locationId); + + lineNumber = lineNumbers.first; + + if (lineNumbers.first != lineNumbers.second) + { + endLineNumber = lineNumbers.second; + } } else { @@ -175,7 +189,12 @@ bool QtCodeFileSingle::requestScroll(const FilePath& filePath, uint lineNumber, } } - ensurePercentVisibleAnimated(double(lineNumber - 1) / m_area->getEndLineNumber(), animated, onTop); + double percentA = double(lineNumber - 1) / m_area->getEndLineNumber(); + double percentB = endLineNumber ? double(endLineNumber - 1) / m_area->getEndLineNumber() : 0.0f; + + ensurePercentVisibleAnimated(percentA, percentB, animated, onTop); + + m_scrollRequested = true; return true; } @@ -206,6 +225,11 @@ const FilePath& QtCodeFileSingle::getCurrentFilePath() const return m_currentFilePath; } +bool QtCodeFileSingle::hasFileCached(const FilePath& filePath) const +{ + return getFileData(filePath).area != nullptr; +} + Id QtCodeFileSingle::getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) const { if (!m_area) @@ -213,7 +237,13 @@ Id QtCodeFileSingle::getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) con return 0; } - return m_area->getLocationIdOfFirstActiveLocationOfTokenId(tokenId); + Id scopeId = m_area->getLocationIdOfFirstActiveScopeLocation(tokenId); + if (scopeId) + { + return scopeId; + } + + return m_area->getLocationIdOfFirstActiveLocation(tokenId); } QtCodeFileSingle::FileData QtCodeFileSingle::getFileData(const FilePath& filePath) const @@ -273,6 +303,8 @@ void QtCodeFileSingle::setFileData(const FileData& file) m_title->show(); m_area->show(); + + m_scrollRequested = false; } else { diff --git a/src/lib_gui/qt/element/QtCodeFileSingle.h b/src/lib_gui/qt/element/QtCodeFileSingle.h index d48cb7ca..d2af7ffb 100644 --- a/src/lib_gui/qt/element/QtCodeFileSingle.h +++ b/src/lib_gui/qt/element/QtCodeFileSingle.h @@ -32,9 +32,9 @@ public: // QtCodeNaviatebale implementation virtual QAbstractScrollArea* getScrollArea() override; - virtual void addCodeSnippet(const CodeSnippetParams& params, bool insert = false) override; + virtual void addCodeSnippet(const CodeSnippetParams& params) override; - void requestFileContent(const FilePath& filePath); + virtual void requestFileContent(const FilePath& filePath) override; virtual bool requestScroll(const FilePath& filePath, uint lineNumber, Id locationId, bool animated, bool onTop) override; virtual void updateFiles() override; @@ -43,6 +43,7 @@ public: virtual void onWindowFocus() override; const FilePath& getCurrentFilePath() const; + bool hasFileCached(const FilePath& filePath) const; Id getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) const; @@ -75,6 +76,7 @@ private: std::deque m_filePaths; bool m_contentRequested; + bool m_scrollRequested; }; #endif // QT_CODE_FILE_SINGLE_H diff --git a/src/lib_gui/qt/element/QtCodeNavigateable.cpp b/src/lib_gui/qt/element/QtCodeNavigateable.cpp index 6e5abe19..84efec1f 100644 --- a/src/lib_gui/qt/element/QtCodeNavigateable.cpp +++ b/src/lib_gui/qt/element/QtCodeNavigateable.cpp @@ -58,7 +58,7 @@ void QtCodeNavigateable::ensureWidgetVisibleAnimated( } } -void QtCodeNavigateable::ensurePercentVisibleAnimated(double percent, bool animated, bool onTop) +void QtCodeNavigateable::ensurePercentVisibleAnimated(double percentA, double percentB, bool animated, bool onTop) { QAbstractScrollArea* area = getScrollArea(); if (!area) @@ -74,10 +74,34 @@ void QtCodeNavigateable::ensurePercentVisibleAnimated(double percent, bool anima return; } - int scrollHeight = totalHeight * percent; + int scrollHeight = totalHeight * percentA; if (!onTop) { - scrollHeight -= visibleHeight / 3; + if (percentB) + { + int scrollHeightB = totalHeight * percentB; + int rectHeight = scrollHeightB - scrollHeight; + + if (rectHeight < visibleHeight) + { + if (rectHeight < visibleHeight / 2) + { + scrollHeight -= visibleHeight / 4; + } + else + { + scrollHeight += rectHeight / 2 - visibleHeight / 2; + } + } + else + { + scrollHeight -= 20; + } + } + else + { + scrollHeight -= visibleHeight / 4; + } } else { diff --git a/src/lib_gui/qt/element/QtCodeNavigateable.h b/src/lib_gui/qt/element/QtCodeNavigateable.h index 097cf37b..ba4931a4 100644 --- a/src/lib_gui/qt/element/QtCodeNavigateable.h +++ b/src/lib_gui/qt/element/QtCodeNavigateable.h @@ -19,8 +19,9 @@ public: virtual QAbstractScrollArea* getScrollArea() = 0; - virtual void addCodeSnippet(const CodeSnippetParams& params, bool insert = false) = 0; + virtual void addCodeSnippet(const CodeSnippetParams& params) = 0; + virtual void requestFileContent(const FilePath& filePath) = 0; virtual bool requestScroll(const FilePath& filePath, uint lineNumber, Id locationId, bool animated, bool onTop) = 0; virtual void updateFiles() = 0; @@ -30,7 +31,7 @@ public: protected: void ensureWidgetVisibleAnimated(QWidget* parentWidget, QWidget *childWidget, QRectF rect, bool animated, bool onTop); - void ensurePercentVisibleAnimated(double percent, bool animated, bool onTop); + void ensurePercentVisibleAnimated(double percentA, double percentB, bool animated, bool onTop); }; #endif // QT_CODE_NAVIGATEABLE_H diff --git a/src/lib_gui/qt/element/QtCodeNavigator.cpp b/src/lib_gui/qt/element/QtCodeNavigator.cpp index 5b2ffba3..bd14ddab 100644 --- a/src/lib_gui/qt/element/QtCodeNavigator.cpp +++ b/src/lib_gui/qt/element/QtCodeNavigator.cpp @@ -8,7 +8,6 @@ #include #include "utility/logging/logging.h" -#include "utility/messaging/type/MessageCodeViewExpandedInitialFiles.h" #include "utility/messaging/type/MessageScrollCode.h" #include "utility/messaging/type/MessageShowErrors.h" #include "utility/ResourcePaths.h" @@ -137,21 +136,30 @@ QtCodeNavigator::~QtCodeNavigator() { } -void QtCodeNavigator::addCodeSnippet(const CodeSnippetParams& params, bool insert) +void QtCodeNavigator::addCodeSnippet(const CodeSnippetParams& params) { + FilePath currentPath = m_single->getCurrentFilePath(); + if (params.reduced) { - m_list->addCodeSnippet(params, insert); - m_single->addCodeSnippet(params, insert); + m_list->addCodeSnippet(params); + m_single->addCodeSnippet(params); } else { - m_current->addCodeSnippet(params, insert); + m_current->addCodeSnippet(params); + } + + if (currentPath != m_single->getCurrentFilePath()) + { + m_singleHasNewFile = true; } } void QtCodeNavigator::addFile(std::shared_ptr locationFile, int refCount, TimePoint modificationTime) { + bool firstFile = m_references.size() == 0; + m_list->addFile(locationFile->getFilePath(), locationFile->isWhole(), refCount, modificationTime, locationFile->isComplete()); if (locationFile->isWhole()) @@ -195,13 +203,26 @@ void QtCodeNavigator::addFile(std::shared_ptr locationFile, } ); } + + if (firstFile && m_references.size() && m_references[0].locationType != LOCATION_TOKEN) + { + clearCaches(); + } } void QtCodeNavigator::addedFiles() { - if (m_references.size() && m_references[0].locationType != LOCATION_TOKEN) + if (m_mode == MODE_SINGLE && m_references.size()) { - clearCaches(); + if (!m_refIndex || !m_activeReference.tokenId) + { + m_single->requestFileContent(m_references.front().filePath); + } + } + + if (m_refIndex == 0) + { + updateRefLabel(); } } @@ -343,6 +364,11 @@ bool QtCodeNavigator::isInListMode() const return m_mode == MODE_LIST; } +bool QtCodeNavigator::hasSingleFileCached(const FilePath& filePath) const +{ + return m_single->hasFileCached(filePath); +} + void QtCodeNavigator::showActiveSnippet( const std::vector& activeTokenIds, std::shared_ptr collection, bool scrollTo) { @@ -425,8 +451,11 @@ void QtCodeNavigator::showActiveSnippet( if (firstReference.tokenId) { - requestScroll(firstReference.filePath, 0, firstReference.locationId, true, false); - emit scrollRequest(); + if (scrollTo) + { + requestScroll(firstReference.filePath, 0, firstReference.locationId, true, false); + emit scrollRequest(); + } m_refIndex = refIndex; updateRefLabel(); @@ -465,46 +494,6 @@ void QtCodeNavigator::setFileMaximized(const FilePath path) m_list->setFileMaximized(path); } -void QtCodeNavigator::setupFiles() -{ - if (m_mode == MODE_LIST) - { - std::set filePathsToExpand; - for (const Reference& ref : m_references) - { - if (filePathsToExpand.find(ref.filePath) == filePathsToExpand.end()) - { - m_list->requestFileContent(ref.filePath, filePathsToExpand.size() == 0); - filePathsToExpand.insert(ref.filePath); - - if (filePathsToExpand.size() >= 3) - { - break; - } - } - } - - if (filePathsToExpand.size()) - { - MessageCodeViewExpandedInitialFiles(m_refIndex != 0 || m_activeReference.tokenId).dispatch(); - } - } - else if (m_references.size()) - { - m_singleHasNewFile = (m_single->getCurrentFilePath() != m_references.front().filePath); - if (!m_refIndex || !m_activeReference.tokenId) - { - m_single->requestFileContent(m_references.front().filePath); - } - MessageCodeViewExpandedInitialFiles(true).dispatch(); - } - - if (m_refIndex == 0) - { - updateRefLabel(); - } -} - void QtCodeNavigator::updateFiles() { m_current->updateFiles(); @@ -555,7 +544,8 @@ void QtCodeNavigator::scrollToValue(int value, bool inListMode) if ((m_mode == MODE_LIST) == inListMode) { m_value = value; - QTimer::singleShot(1000, this, SLOT(setValue())); + QTimer::singleShot(100, this, SLOT(setValue())); + m_scrollRequest = ScrollRequest(); } } @@ -565,7 +555,7 @@ void QtCodeNavigator::scrollToLine(const FilePath& filePath, unsigned int line) emit scrollRequest(); } -void QtCodeNavigator::scrollToDefinition(bool ignoreActiveReference) +void QtCodeNavigator::scrollToDefinition(bool animated, bool ignoreActiveReference) { if (ignoreActiveReference) { @@ -594,25 +584,25 @@ void QtCodeNavigator::scrollToDefinition(bool ignoreActiveReference) return; } - if (!m_activeTokenId && m_mode == MODE_SINGLE && m_references.size() && m_references.front().locationType != LOCATION_TOKEN) - { - requestScroll(m_references.front().filePath, 0, m_references.front().locationId, false, true); - emit scrollRequest(); - return; - } - if (!m_activeTokenId) { + if (m_mode == MODE_SINGLE && m_references.size() && m_references.front().locationType != LOCATION_TOKEN) + { + requestScroll(m_references.front().filePath, 0, m_references.front().locationId, false, false); + emit scrollRequest(); + } return; } if (m_mode == MODE_LIST) { - std::pair result = m_list->getFirstSnippetWithActiveLocation(m_activeTokenId); + std::cout << animated << std::endl; + std::pair result = m_list->getFirstSnippetWithActiveLocationId(m_activeTokenId); if (result.first != nullptr) { - requestScroll(result.first->getFile()->getFilePath(), result.second, 0, false, true); + requestScroll(result.first->getFile()->getFilePath(), 0, result.second, animated, false); emit scrollRequest(); + return; } } else @@ -620,22 +610,18 @@ void QtCodeNavigator::scrollToDefinition(bool ignoreActiveReference) Id locationId = m_single->getLocationIdOfFirstActiveLocationOfTokenId(m_activeTokenId); if (locationId) { - for (size_t i = 0; i < m_references.size(); i++) - { - if (m_references[i].locationId == locationId) - { - m_refIndex = i + 1; - showCurrentReference(false); - } - } - } - else if (m_references.size()) - { - nextReference(false); + requestScroll(m_single->getCurrentFilePath(), 0, locationId, true, false); + emit scrollRequest(); + return; } } - //m_singleHasNewFile = false; + if (m_references.size()) + { + m_current->requestFileContent(m_references.front().filePath); + requestScroll(m_references.front().filePath, 0, m_references.front().locationId, false, false); + emit scrollRequest(); + } } void QtCodeNavigator::scrollToSnippetIfRequested() @@ -658,10 +644,6 @@ void QtCodeNavigator::requestScroll(const FilePath& filePath, uint lineNumber, I { req.animated = false; } - else - { - req.animated = (m_single->getCurrentFilePath() == filePath); - } } // std::cout << "scroll request: " << req.filePath.str() << " " << req.lineNumber << " " << req.locationId; @@ -688,6 +670,10 @@ void QtCodeNavigator::handleScrollRequest() { m_scrollRequest = ScrollRequest(); } + else if (m_mode == MODE_SINGLE) + { + m_scrollRequest.animated = false; + } } void QtCodeNavigator::scrolled(int value) @@ -789,7 +775,7 @@ void QtCodeNavigator::setMode(Mode mode) ApplicationSettings::getInstance()->setCodeViewModeSingle(m_mode == MODE_SINGLE); ApplicationSettings::getInstance()->save(); - setupFiles(); + scrollToDefinition(false, false); showContents(); } @@ -859,7 +845,7 @@ void QtCodeNavigator::handleMessage(MessageShowReference* message) setCurrentActiveLocationIds(std::vector(1, ref.locationId)); updateFiles(); - requestScroll(ref.filePath, 0, ref.locationId, message->animated, false); + requestScroll(ref.filePath, 0, ref.locationId, true, false); emit scrollRequest(); if (ref.locationType == LOCATION_ERROR) diff --git a/src/lib_gui/qt/element/QtCodeNavigator.h b/src/lib_gui/qt/element/QtCodeNavigator.h index 52c6bffd..b25b20f5 100644 --- a/src/lib_gui/qt/element/QtCodeNavigator.h +++ b/src/lib_gui/qt/element/QtCodeNavigator.h @@ -34,7 +34,7 @@ public: QtCodeNavigator(QWidget* parent = nullptr); virtual ~QtCodeNavigator(); - void addCodeSnippet(const CodeSnippetParams& params, bool insert = false); + void addCodeSnippet(const CodeSnippetParams& params); void addFile(std::shared_ptr locationFile, int refCount, TimePoint modificationTime); void addedFiles(); @@ -65,6 +65,7 @@ public: size_t getFatalErrorCountForFile(const FilePath& filePath) const; bool isInListMode() const; + bool hasSingleFileCached(const FilePath& filePath) const; void showActiveSnippet( const std::vector& activeTokenIds, std::shared_ptr collection, bool scrollTo); @@ -76,7 +77,6 @@ public: void setFileSnippets(const FilePath path); void setFileMaximized(const FilePath path); - void setupFiles(); void updateFiles(); void showContents(); @@ -84,7 +84,7 @@ public: void scrollToValue(int value, bool inListMode); void scrollToLine(const FilePath& filePath, unsigned int line); - void scrollToDefinition(bool ignoreActiveReference); + void scrollToDefinition(bool animated, bool ignoreActiveReference); void scrollToSnippetIfRequested(); diff --git a/src/lib_gui/qt/element/QtCodeSnippet.cpp b/src/lib_gui/qt/element/QtCodeSnippet.cpp index ce94e280..f8963dc7 100644 --- a/src/lib_gui/qt/element/QtCodeSnippet.cpp +++ b/src/lib_gui/qt/element/QtCodeSnippet.cpp @@ -164,9 +164,20 @@ uint QtCodeSnippet::getLineNumberForLocationId(Id locationId) const return m_codeArea->getLineNumberForLocationId(locationId); } -uint QtCodeSnippet::getStartLineNumberOfFirstActiveLocationOfTokenId(Id tokenId) const +std::pair QtCodeSnippet::getLineNumbersForLocationId(Id locationId) const { - return m_codeArea->getStartLineNumberOfFirstActiveLocationOfTokenId(tokenId); + return m_codeArea->getLineNumbersForLocationId(locationId); +} + +Id QtCodeSnippet::getFirstActiveLocationId(Id tokenId) const +{ + Id scopeId = m_codeArea->getLocationIdOfFirstActiveScopeLocation(tokenId); + if (scopeId) + { + return scopeId; + } + + return m_codeArea->getLocationIdOfFirstActiveLocation(tokenId); } QRectF QtCodeSnippet::getLineRectForLineNumber(uint lineNumber) const diff --git a/src/lib_gui/qt/element/QtCodeSnippet.h b/src/lib_gui/qt/element/QtCodeSnippet.h index a941dc52..ed43e80f 100644 --- a/src/lib_gui/qt/element/QtCodeSnippet.h +++ b/src/lib_gui/qt/element/QtCodeSnippet.h @@ -44,7 +44,9 @@ public: void setIsActiveFile(bool isActiveFile); uint getLineNumberForLocationId(Id locationId) const; - uint getStartLineNumberOfFirstActiveLocationOfTokenId(Id tokenId) const; + std::pair getLineNumbersForLocationId(Id locationId) const; + + Id getFirstActiveLocationId(Id tokenId) 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 82ce995d..8ca07649 100644 --- a/src/lib_gui/qt/view/QtCodeView.cpp +++ b/src/lib_gui/qt/view/QtCodeView.cpp @@ -1,25 +1,16 @@ #include "qt/view/QtCodeView.h" #include "utility/ResourcePaths.h" -#include "qt/utility/utilityQt.h" #include "qt/element/QtCodeArea.h" #include "qt/element/QtCodeNavigator.h" #include "qt/utility/QtHighlighter.h" +#include "qt/utility/utilityQt.h" #include "qt/view/QtViewWidgetWrapper.h" #include "settings/ColorScheme.h" QtCodeView::QtCodeView(ViewLayout* viewLayout) : CodeView(viewLayout) - , m_showCodeSnippetsFunctor( - std::bind(&QtCodeView::doShowCodeSnippets, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) - , m_addCodeSnippetsFunctor(std::bind(&QtCodeView::doAddCodeSnippets, this, std::placeholders::_1, std::placeholders::_2)) - , m_setFileStateFunctor(std::bind(&QtCodeView::doSetFileState, this, std::placeholders::_1, std::placeholders::_2)) - , m_doShowActiveSnippetFunctor( - std::bind(&QtCodeView::doShowActiveSnippet, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) - , m_doShowActiveTokenIdsFunctor(std::bind(&QtCodeView::doShowActiveTokenIds, this, std::placeholders::_1)) - , m_doShowActiveLocalSymbolIdsFunctor(std::bind(&QtCodeView::doShowActiveLocalSymbolIds, this, std::placeholders::_1)) - , m_focusTokenIdsFunctor(std::bind(&QtCodeView::doFocusTokenIds, this, std::placeholders::_1)) { m_widget = new QtCodeNavigator(); setStyleSheet(); @@ -40,138 +31,156 @@ void QtCodeView::initView() void QtCodeView::refreshView() { - m_onQtThread( - [=]() - { - setStyleSheet(); + m_onQtThread([=]() + { + setStyleSheet(); - m_widget->refreshStyle(); + m_widget->refreshStyle(); - QtCodeArea::clearAnnotationColors(); - QtHighlighter::clearHighlightingRules(); - } - ); + QtCodeArea::clearAnnotationColors(); + QtHighlighter::clearHighlightingRules(); + }); } void QtCodeView::clear() { - m_onQtThread( - [=]() - { - m_widget->clear(); - } - ); + m_onQtThread([=]() + { + m_widget->clear(); + }); - m_errorInfos.clear(); -} - -void QtCodeView::clearCodeSnippets() -{ - m_onQtThread( - [=]() - { - m_widget->clearCodeSnippets(); - } - ); - - m_errorInfos.clear(); -} - -void QtCodeView::setErrorInfos(const std::vector& errorInfos) -{ - m_errorInfos = errorInfos; + m_scrollParams = ScrollParams(); } bool QtCodeView::showsErrors() const { - return m_errorInfos.size() > 0; + return m_widget->hasErrors(); } -void QtCodeView::showCodeSnippets( - const std::vector& snippets, const std::vector& activeTokenIds, bool setupFiles) +void QtCodeView::showCodeSnippets(const std::vector& snippets, const CodeParams params) { - m_showCodeSnippetsFunctor(snippets, activeTokenIds, setupFiles); + m_onQtThread([=]() + { + if (params.clearSnippets) + { + m_widget->clearCodeSnippets(); + + m_widget->setActiveTokenIds(params.activeTokenIds); + m_widget->setErrorInfos(params.errorInfos); + } + + bool addedFiles = false; + + for (const CodeSnippetParams& snippet : snippets) + { + if (snippet.isCollapsed) + { + m_widget->addFile(snippet.locationFile, snippet.refCount, snippet.modificationTime); + + addedFiles = true; + } + else + { + m_widget->addCodeSnippet(snippet); + } + } + + if (addedFiles) + { + m_widget->addedFiles(); + } + + m_widget->updateFiles(); + + if (m_widget->isInListMode()) + { + setStyleSheet(); // so property "isLast" of QtCodeSnippet is computed correctly + } + + if (params.showContents) + { + m_widget->showContents(); + performScroll(); + } + }); } -void QtCodeView::addCodeSnippets(const std::vector& snippets, bool insert) +void QtCodeView::scrollTo(const ScrollParams params) { - m_addCodeSnippetsFunctor(snippets, insert); + m_scrollParams = params; } void QtCodeView::setFileState(const FilePath filePath, FileState state) { - m_setFileStateFunctor(filePath, state); + m_onQtThread([=]() + { + switch (state) + { + case FILE_MINIMIZED: + m_widget->setFileMinimized(filePath); + break; + case FILE_SNIPPETS: + m_widget->setFileSnippets(filePath); + break; + case FILE_MAXIMIZED: + m_widget->setFileMaximized(filePath); + break; + } + }); } void QtCodeView::showActiveSnippet( const std::vector& activeTokenIds, std::shared_ptr collection, bool scrollTo) { - m_doShowActiveSnippetFunctor(activeTokenIds, collection, scrollTo); + m_onQtThread([=]() + { + m_widget->showActiveSnippet(activeTokenIds, collection, scrollTo); + }); } void QtCodeView::showActiveTokenIds(const std::vector& activeTokenIds) { - m_doShowActiveTokenIdsFunctor(activeTokenIds); + m_onQtThread([=]() + { + m_widget->setActiveTokenIds(activeTokenIds); + m_widget->updateFiles(); + + performScroll(); + }); } void QtCodeView::showActiveLocalSymbolIds(const std::vector& activeLocalSymbolIds) { - m_doShowActiveLocalSymbolIdsFunctor(activeLocalSymbolIds); + m_onQtThread([=]() + { + m_widget->setActiveLocalSymbolIds(activeLocalSymbolIds); + m_widget->updateFiles(); + }); } void QtCodeView::focusTokenIds(const std::vector& focusedTokenIds) { - m_focusTokenIdsFunctor(focusedTokenIds); + m_onQtThread([=]() + { + m_widget->focusTokenIds(focusedTokenIds); + }); } void QtCodeView::defocusTokenIds() { - m_onQtThread( - [=]() - { - m_widget->defocusTokenIds(); - } - ); + m_onQtThread([=]() + { + m_widget->defocusTokenIds(); + }); } void QtCodeView::showContents() { - m_onQtThread( - [=]() - { - m_widget->showContents(); - } - ); -} - -void QtCodeView::scrollToValue(int value, bool inListMode) -{ - m_onQtThread( - [=]() - { - m_widget->scrollToValue(value, inListMode); - } - ); -} - -void QtCodeView::scrollToLine(const FilePath filePath, unsigned int line) -{ - m_onQtThread( - [=]() - { - m_widget->scrollToLine(filePath, line); - } - ); -} - -void QtCodeView::scrollToDefinition(bool ignoreActiveReference) -{ - m_onQtThread( - [=]() - { - m_widget->scrollToDefinition(ignoreActiveReference); - } - ); + m_onQtThread([=]() + { + m_widget->showContents(); + performScroll(); + }); } bool QtCodeView::isInListMode() const @@ -179,87 +188,31 @@ bool QtCodeView::isInListMode() const return m_widget->isInListMode(); } -void QtCodeView::doShowCodeSnippets( - const std::vector& snippets, const std::vector& activeTokenIds, bool setupFiles) +bool QtCodeView::hasSingleFileCached(const FilePath& filePath) const { - m_widget->setActiveTokenIds(activeTokenIds); - m_widget->setErrorInfos(m_errorInfos); - - for (const CodeSnippetParams& params : snippets) - { - if (params.isCollapsed) - { - m_widget->addFile(params.locationFile, params.refCount, params.modificationTime); - } - else - { - m_widget->addCodeSnippet(params); - } - } - - m_widget->addedFiles(); - - if (setupFiles) - { - m_widget->setupFiles(); - } - - setStyleSheet(); // so property "isLast" of QtCodeSnippet is computed correctly + return m_widget->hasSingleFileCached(filePath); } -void QtCodeView::doAddCodeSnippets(const std::vector& snippets, bool insert) +void QtCodeView::performScroll() { - for (const CodeSnippetParams& params : snippets) + switch (m_scrollParams.type) { - m_widget->addCodeSnippet(params, insert); - } - - m_widget->updateFiles(); - - setStyleSheet(); // so property "isLast" of QtCodeSnippet is computed correctly - - m_widget->scrollToSnippetIfRequested(); -} - -void QtCodeView::doSetFileState(const FilePath filePath, FileState state) -{ - switch (state) - { - case FILE_MINIMIZED: - m_widget->setFileMinimized(filePath); + case ScrollParams::SCROLL_TO_DEFINITION: + m_widget->scrollToDefinition(m_scrollParams.animated, m_scrollParams.ignoreActiveReference); break; - case FILE_SNIPPETS: - m_widget->setFileSnippets(filePath); + case ScrollParams::SCROLL_TO_LINE: + m_widget->scrollToLine(m_scrollParams.filePath, m_scrollParams.line); break; - case FILE_MAXIMIZED: - m_widget->setFileMaximized(filePath); + case ScrollParams::SCROLL_TO_VALUE: + m_widget->scrollToValue(m_scrollParams.value, m_scrollParams.inListMode); + break; + default: break; } m_widget->scrollToSnippetIfRequested(); -} -void QtCodeView::doShowActiveSnippet( - const std::vector& activeTokenIds, std::shared_ptr collection, bool scrollTo) -{ - m_widget->showActiveSnippet(activeTokenIds, collection, scrollTo); -} - -void QtCodeView::doShowActiveTokenIds(const std::vector& activeTokenIds) -{ - m_widget->setActiveTokenIds(activeTokenIds); - m_widget->updateFiles(); -} - -void QtCodeView::doShowActiveLocalSymbolIds(const std::vector& localSymbolIds) -{ - m_widget->setActiveLocalSymbolIds(localSymbolIds); - m_widget->updateFiles(); -} - -void QtCodeView::doFocusTokenIds(const std::vector& focusedTokenIds) -{ - m_widget->focusTokenIds(focusedTokenIds); + m_scrollParams = ScrollParams(); } void QtCodeView::setStyleSheet() const diff --git a/src/lib_gui/qt/view/QtCodeView.h b/src/lib_gui/qt/view/QtCodeView.h index dd988dbb..c5fd4297 100644 --- a/src/lib_gui/qt/view/QtCodeView.h +++ b/src/lib_gui/qt/view/QtCodeView.h @@ -1,17 +1,10 @@ #ifndef QT_CODE_VIEW_H #define QT_CODE_VIEW_H -#include -#include - -#include "utility/types.h" - #include "component/view/CodeView.h" #include "qt/utility/QtThreadedFunctor.h" -class QFrame; class QtCodeNavigator; -class QWidget; class QtCodeView : public CodeView @@ -27,15 +20,12 @@ public: // CodeView implementation virtual void clear(); - virtual void clearCodeSnippets(); - virtual void setErrorInfos(const std::vector& errorInfos); + virtual void showCodeSnippets(const std::vector& snippets, const CodeParams params); + virtual void scrollTo(const ScrollParams params); + virtual bool showsErrors() const; - virtual void showCodeSnippets( - const std::vector& snippets, const std::vector& activeTokenIds, bool setupFiles); - virtual void addCodeSnippets(const std::vector& snippets, bool insert); - virtual void setFileState(const FilePath filePath, FileState state); virtual void showActiveSnippet( @@ -48,41 +38,20 @@ public: virtual void showContents(); - virtual void scrollToValue(int value, bool inListMode); - virtual void scrollToLine(const FilePath filePath, unsigned int line); - virtual void scrollToDefinition(bool ignoreActiveReference); - virtual bool isInListMode() const; + virtual bool hasSingleFileCached(const FilePath& filePath) const; + + private: - void doShowCodeSnippets( - const std::vector& snippets, const std::vector& activeTokenIds, bool setupFiles); - void doAddCodeSnippets(const std::vector& snippets, bool insert); - - void doSetFileState(const FilePath filePath, FileState state); - - void doShowActiveSnippet( - const std::vector& activeTokenIds, std::shared_ptr collection, bool scrollTo); - void doShowActiveTokenIds(const std::vector& activeTokenIds); - void doShowActiveLocalSymbolIds(const std::vector& localSymbolIds); - - void doFocusTokenIds(const std::vector& focusedTokenIds); - + void performScroll(); void setStyleSheet() const; - QtThreadedFunctor&, const std::vector&, bool> m_showCodeSnippetsFunctor; - QtThreadedFunctor&, bool> m_addCodeSnippetsFunctor; - QtThreadedFunctor m_setFileStateFunctor; - QtThreadedFunctor&, std::shared_ptr, bool> m_doShowActiveSnippetFunctor; - QtThreadedFunctor&> m_doShowActiveTokenIdsFunctor; - QtThreadedFunctor&> m_doShowActiveLocalSymbolIdsFunctor; - QtThreadedFunctor&> m_focusTokenIdsFunctor; - QtThreadedLambdaFunctor m_onQtThread; QtCodeNavigator* m_widget; - std::vector m_errorInfos; + ScrollParams m_scrollParams; }; # endif // QT_CODE_VIEW_H