diff --git a/src/app/qt/element/QtCodeFile.cpp b/src/app/qt/element/QtCodeFile.cpp index 779303c3..8625b15d 100644 --- a/src/app/qt/element/QtCodeFile.cpp +++ b/src/app/qt/element/QtCodeFile.cpp @@ -4,10 +4,11 @@ #include #include "qt/element/QtCodeSnippet.h" +#include "utility/FileSystem.h" -QtCodeFile::QtCodeFile(const std::string& fileName, QWidget *parent) +QtCodeFile::QtCodeFile(const std::string& filePath, QWidget *parent) : QWidget(parent) - , m_fileName(fileName) + , m_filePath(filePath) , m_showMaximizeButton(true) { setObjectName("code_file"); @@ -18,10 +19,10 @@ QtCodeFile::QtCodeFile(const std::string& fileName, QWidget *parent) layout->setAlignment(Qt::AlignTop); setLayout(layout); - QLabel* label = new QLabel(fileName.c_str(), this); + QLabel* label = new QLabel(FileSystem::fileName(filePath).c_str(), this); label->setObjectName("title_label"); label->minimumSizeHint(); // force font loading - label->setFixedWidth(label->fontMetrics().width(fileName.c_str()) + 32); + label->setFixedWidth(label->fontMetrics().width(FileSystem::fileName(filePath).c_str()) + 32); label->setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed); layout->addWidget(label); } @@ -30,9 +31,9 @@ QtCodeFile::~QtCodeFile() { } -const std::string& QtCodeFile::getFileName() const +std::string QtCodeFile::getFileName() const { - return m_fileName; + return FileSystem::fileName(m_filePath); } void QtCodeFile::addCodeSnippet( diff --git a/src/app/qt/element/QtCodeFile.h b/src/app/qt/element/QtCodeFile.h index 721df269..c850c6aa 100644 --- a/src/app/qt/element/QtCodeFile.h +++ b/src/app/qt/element/QtCodeFile.h @@ -15,10 +15,10 @@ class TokenLocationFile; class QtCodeFile : public QWidget { public: - QtCodeFile(const std::string& fileName, QWidget *parent = 0); + QtCodeFile(const std::string& filePath, QWidget *parent = 0); virtual ~QtCodeFile(); - const std::string& getFileName() const; + std::string getFileName() const; void addCodeSnippet( uint startLineNumber, @@ -32,7 +32,7 @@ public: private: std::vector > m_snippets; - const std::string m_fileName; + const std::string m_filePath; bool m_showMaximizeButton; }; diff --git a/src/app/qt/element/QtCodeFileList.cpp b/src/app/qt/element/QtCodeFileList.cpp index c51467af..b32a2a68 100644 --- a/src/app/qt/element/QtCodeFileList.cpp +++ b/src/app/qt/element/QtCodeFileList.cpp @@ -48,7 +48,7 @@ void QtCodeFileList::addCodeSnippet( if (!file) { - std::shared_ptr filePtr = std::make_shared(fileName, this); + std::shared_ptr filePtr = std::make_shared(locationFile.getFilePath(), this); m_files.push_back(filePtr); file = filePtr.get(); diff --git a/src/app/qt/view/QtCodeView.cpp b/src/app/qt/view/QtCodeView.cpp index edfedbf7..3ac91bdd 100644 --- a/src/app/qt/view/QtCodeView.cpp +++ b/src/app/qt/view/QtCodeView.cpp @@ -67,7 +67,7 @@ void QtCodeView::doShowCodeFile(const CodeSnippetParams& params) m_windows.push_back(ptr); ptr->setShowMaximizeButton(false); - ptr->addCodeSnippet(1, params.code, params.locationFile, params.activeTokenIds); + ptr->addCodeSnippet(1, params.code, params.locationFile, m_activeTokenIds); ptr->setWindowTitle(FileSystem::fileName(params.locationFile.getFilePath()).c_str()); ptr->show(); @@ -81,12 +81,12 @@ void QtCodeView::doShowCodeFile(const CodeSnippetParams& params) void QtCodeView::doAddCodeSnippet(const CodeSnippetParams& params) { - m_widget->addCodeSnippet(params.startLineNumber, params.code, params.locationFile, params.activeTokenIds); + m_widget->addCodeSnippet(params.startLineNumber, params.code, params.locationFile, m_activeTokenIds); clearClosedWindows(); for (std::shared_ptr window: m_windows) { - window->setActiveTokenIds(params.activeTokenIds); + window->setActiveTokenIds(m_activeTokenIds); } } @@ -107,6 +107,11 @@ void QtCodeView::setStyleSheet(QWidget* widget) const widget->setStyleSheet(TextAccess::createFromFile("data/gui/code_view/code_view.css")->getText().c_str()); } +void QtCodeView::setActiveTokenIds(std::vector ids) +{ + m_activeTokenIds = ids; +} + void QtCodeView::clearClosedWindows() { for (size_t i = 0; i < m_windows.size(); i++) diff --git a/src/app/qt/view/QtCodeView.h b/src/app/qt/view/QtCodeView.h index 6870bde3..98954977 100644 --- a/src/app/qt/view/QtCodeView.h +++ b/src/app/qt/view/QtCodeView.h @@ -37,7 +37,7 @@ private: std::shared_ptr createQtCodeFileList() const; void setStyleSheet(QWidget* widget) const; - + void setActiveTokenIds(std::vector ids); void clearClosedWindows(); QtThreadedFunctor<> m_refreshViewFunctor; @@ -47,6 +47,7 @@ private: std::shared_ptr m_widget; std::vector> m_windows; + std::vector m_activeTokenIds; }; # endif // QT_CODE_VIEW_H diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 6b9a14c8..67b05eed 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -8,6 +8,8 @@ #include "data/location/TokenLocationFile.h" #include "utility/text/TextAccess.h" +const uint CodeController::s_lineRadius = 2; + CodeController::CodeController(GraphAccess* graphAccess, LocationAccess* locationAccess) : m_graphAccess(graphAccess) , m_locationAccess(locationAccess) @@ -18,26 +20,29 @@ CodeController::~CodeController() { } -void CodeController::setActiveTokenIds(const std::vector& ids) +void CodeController::setActiveTokenIds(const std::vector& ids, Id activeId, Id declarationId) { - const uint lineRadius = 2; - getView()->clearCodeSnippets(); + getView()->setActiveTokenIds(ids); std::vector locationIds = m_graphAccess->getLocationIdsForTokenIds(ids); + std::vector snippets; + TokenLocationCollection collection = m_locationAccess->getTokenLocationsForLocationIds(locationIds); + collection.forEachTokenLocationFile( [&](TokenLocationFile* file) -> void { const std::string filePath = file->getFilePath(); std::shared_ptr textAccess = TextAccess::createFromFile(filePath); - std::vector> ranges = getSnippetRangesForFile(file, lineRadius); + std::vector> ranges = getSnippetRangesForFile(file, s_lineRadius); + for (const std::pair& range: ranges) { - unsigned int firstLineNumber = std::max(1, range.first - lineRadius); - unsigned int lastLineNumber = std::min(textAccess->getLineCount(), range.second + lineRadius); + unsigned int firstLineNumber = std::max(1, range.first - s_lineRadius); + unsigned int lastLineNumber = std::min(textAccess->getLineCount(), range.second + s_lineRadius); CodeView::CodeSnippetParams params; for (const std::string& line: textAccess->getLines(firstLineNumber, lastLineNumber)) @@ -47,31 +52,52 @@ void CodeController::setActiveTokenIds(const std::vector& ids) params.startLineNumber = firstLineNumber; params.locationFile = - m_locationAccess->getTokenLocationsForLinesInFile(filePath, firstLineNumber, lastLineNumber); - params.activeTokenIds = ids; + m_locationAccess->getTokenLocationsForLinesInFile(filePath, firstLineNumber, lastLineNumber); + params.locationFile.forEachTokenLocation( + [&](TokenLocation* location) + { + if(location->getTokenId() == activeId && activeId != 0) + { + params.isActive = true; + } + if(location->getTokenId() == declarationId && declarationId != 0) + { + params.isDeclaration = true; + } + } + ); - getView()->addCodeSnippet(params); + snippets.push_back(params); } } ); + + std::sort(snippets.begin(), snippets.end(), CodeView::CodeSnippetParams::sort); + + for( CodeView::CodeSnippetParams p : snippets) + { + getView()->addCodeSnippet(p); + } } void CodeController::handleMessage(MessageActivateToken* message) { - std::vector activeTokenIds = m_graphAccess->getActiveTokenIdsForId(message->tokenId); - setActiveTokenIds(activeTokenIds); + Id declarationId; + std::vector activeTokenIds = m_graphAccess->getActiveTokenIdsForId(message->tokenId, declarationId); + setActiveTokenIds(activeTokenIds, message->tokenId, declarationId); } void CodeController::handleMessage(MessageActivateTokens* message) { - if (message->tokenIds.size() == 1) + if (message->tokenIds.size () == 1) { - std::vector activeTokenIds = m_graphAccess->getActiveTokenIdsForId(message->tokenIds[0]); - setActiveTokenIds(activeTokenIds); + Id declarationId; + std::vector activeTokenIds = m_graphAccess->getActiveTokenIdsForId(message->tokenIds[0], declarationId); + setActiveTokenIds(activeTokenIds, message->tokenIds[0], declarationId); } else { - setActiveTokenIds(message->tokenIds); + setActiveTokenIds(message->tokenIds, 0, 0); } } @@ -85,7 +111,7 @@ void CodeController::handleMessage(MessageShowFile* message) CodeView::CodeSnippetParams params; params.startLineNumber = message->startLineNumber; params.endLineNumber = message->endLineNumber; - params.activeTokenIds = message->activeTokenIds; + getView()->setActiveTokenIds(message->activeTokenIds); std::shared_ptr textAccess = TextAccess::createFromFile(message->filePath); params.lineCount = textAccess->getLineCount(); diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index a5838a95..f984dd16 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -33,7 +33,7 @@ public: CodeController(GraphAccess* graphAccess, LocationAccess* locationAccess); ~CodeController(); - void setActiveTokenIds(const std::vector& ids); + void setActiveTokenIds(const std::vector& ids, Id activeId, Id declarationId); private: virtual void handleMessage(MessageActivateToken* message); @@ -43,6 +43,8 @@ private: CodeView* getView(); + static const uint s_lineRadius; + std::vector> getSnippetRangesForFile(TokenLocationFile* file, const uint lineRadius) const; GraphAccess* m_graphAccess; diff --git a/src/lib/component/view/CodeView.cpp b/src/lib/component/view/CodeView.cpp index 52c1334c..1d7d1568 100644 --- a/src/lib/component/view/CodeView.cpp +++ b/src/lib/component/view/CodeView.cpp @@ -1,12 +1,56 @@ #include "component/view/CodeView.h" #include "component/controller/CodeController.h" +#include "utility/FileSystem.h" CodeView::CodeSnippetParams::CodeSnippetParams() - : locationFile("") + : startLineNumber(0) + , endLineNumber(0) + , lineCount(0) + , locationFile("") + , isActive(false) + , isDeclaration(false) { } +bool CodeView::CodeSnippetParams::sort( CodeSnippetParams a, CodeSnippetParams b ) +{ + // sort active snippet first + if(a.isActive) + { + return true; + } + if(b.isActive) + { + return false; + } + // sort declarations + if(a.isDeclaration && !b.isDeclaration) + { + return true; + } + else if (!a.isDeclaration && b.isDeclaration) + { + return false; + } + else + { + // first header + if( FileSystem::filePathWithoutExtension(a.locationFile.getFilePath()) + == FileSystem::filePathWithoutExtension(b.locationFile.getFilePath()) ) + { + return FileSystem::extension(a.locationFile.getFilePath()) + > FileSystem::extension(b.locationFile.getFilePath()); + } + // alphabetical filepath without extension + else + { + return FileSystem::filePathWithoutExtension(a.locationFile.getFilePath()) + < FileSystem::filePathWithoutExtension(b.locationFile.getFilePath()); + } + } +} + CodeView::CodeView(ViewLayout* viewLayout) : View(viewLayout, Vec2i(100, 100)) { diff --git a/src/lib/component/view/CodeView.h b/src/lib/component/view/CodeView.h index 4d00d090..1dc48a2d 100644 --- a/src/lib/component/view/CodeView.h +++ b/src/lib/component/view/CodeView.h @@ -19,8 +19,14 @@ public: uint lineCount; std::string code; - TokenLocationFile locationFile; - std::vector activeTokenIds; + + TokenLocationFile locationFile; + + bool isActive; + bool isDeclaration; + + //comparefunctions for snippetsorting + static bool sort(CodeSnippetParams a, CodeSnippetParams b); }; CodeView(ViewLayout* viewLayout); @@ -31,6 +37,7 @@ public: virtual void showCodeFile(const CodeSnippetParams& params) = 0; virtual void addCodeSnippet(const CodeSnippetParams& params) = 0; virtual void clearCodeSnippets() = 0; + virtual void setActiveTokenIds(std::vector ids) = 0; private: CodeController* getController(); diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index a820d737..a15b2b4e 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -392,7 +392,7 @@ std::shared_ptr Storage::getGraphForActiveTokenIds(const std::vector& return graph; } -std::vector Storage::getActiveTokenIdsForId(Id tokenId) const +std::vector Storage::getActiveTokenIdsForId(Id tokenId, Id& declarationId) const { std::vector ret; Token* token = m_graph.getTokenById(tokenId); @@ -401,17 +401,22 @@ std::vector Storage::getActiveTokenIdsForId(Id tokenId) const return ret; } + ret.push_back(token->getId()); + Node* node; if (token->isEdge()) { node = dynamic_cast(token)->getTo(); + declarationId = node->getId(); + ret.push_back(node->getId()); } else - { + { node = dynamic_cast(token); + declarationId = node->getId(); } - ret.push_back(node->getId()); + //ret.push_back(node->getId()); node->forEachEdge( [&node, &ret](Edge* e) diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 3b0a20d3..3d548389 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -75,7 +75,7 @@ public: virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const; - virtual std::vector getActiveTokenIdsForId(Id tokenId) const; + virtual std::vector getActiveTokenIdsForId(Id tokenId, Id& declarationId) const; virtual std::vector getLocationIdsForTokenIds(const std::vector& tokenIds) const; virtual std::vector getTokenIdsForQuery(std::string query) const; diff --git a/src/lib/data/access/GraphAccess.h b/src/lib/data/access/GraphAccess.h index 403f8988..003cbf10 100644 --- a/src/lib/data/access/GraphAccess.h +++ b/src/lib/data/access/GraphAccess.h @@ -20,7 +20,7 @@ public: virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const = 0; - virtual std::vector getActiveTokenIdsForId(Id tokenId) const = 0; + virtual std::vector getActiveTokenIdsForId(Id tokenId, Id& declarationId) const = 0; virtual std::vector getLocationIdsForTokenIds(const std::vector& tokenIds) const = 0; virtual std::vector getTokenIdsForQuery(std::string query) const = 0; diff --git a/src/lib/data/access/GraphAccessProxy.cpp b/src/lib/data/access/GraphAccessProxy.cpp index f04b1c18..77318df8 100644 --- a/src/lib/data/access/GraphAccessProxy.cpp +++ b/src/lib/data/access/GraphAccessProxy.cpp @@ -67,11 +67,11 @@ std::shared_ptr GraphAccessProxy::getGraphForActiveTokenIds(const std::ve return std::make_shared(); } -std::vector GraphAccessProxy::getActiveTokenIdsForId(Id tokenId) const +std::vector GraphAccessProxy::getActiveTokenIdsForId(Id tokenId, Id& delcarationId) const { if (hasSubject()) { - return m_subject->getActiveTokenIdsForId(tokenId); + return m_subject->getActiveTokenIdsForId(tokenId, delcarationId); } return std::vector(); diff --git a/src/lib/data/access/GraphAccessProxy.h b/src/lib/data/access/GraphAccessProxy.h index 66396e38..3c9893cc 100644 --- a/src/lib/data/access/GraphAccessProxy.h +++ b/src/lib/data/access/GraphAccessProxy.h @@ -19,7 +19,7 @@ public: virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const; - virtual std::vector getActiveTokenIdsForId(Id tokenId) const; + virtual std::vector getActiveTokenIdsForId(Id tokenId, Id& declarationId) const; virtual std::vector getLocationIdsForTokenIds(const std::vector& tokenIds) const; virtual std::vector getTokenIdsForQuery(std::string query) const; diff --git a/src/lib/utility/FileSystem.cpp b/src/lib/utility/FileSystem.cpp index d3ed0e8e..9aee8a21 100644 --- a/src/lib/utility/FileSystem.cpp +++ b/src/lib/utility/FileSystem.cpp @@ -55,3 +55,13 @@ std::string FileSystem::fileName(const std::string& path) { return boost::filesystem::path(path).filename().generic_string(); } + +std::string FileSystem::extension(const std::string& path) +{ + return boost::filesystem::path(path).extension().generic_string(); +} + +std::string FileSystem::filePathWithoutExtension(const std::string& path) +{ + return boost::filesystem::path(path).replace_extension().generic_string(); +} \ No newline at end of file diff --git a/src/lib/utility/FileSystem.h b/src/lib/utility/FileSystem.h index a96c6b0b..d0d20d11 100644 --- a/src/lib/utility/FileSystem.h +++ b/src/lib/utility/FileSystem.h @@ -17,6 +17,8 @@ public: static bool exists(const std::string& path); static std::string fileName(const std::string& path); + static std::string extension(const std::string& path); + static std::string filePathWithoutExtension(const std::string& path); private: static bool isValidExtension(const std::string& filepath, const std::vector& extensions); diff --git a/src/test/FileSystemTestSuite.h b/src/test/FileSystemTestSuite.h index 9907b44f..05c5fb6d 100644 --- a/src/test/FileSystemTestSuite.h +++ b/src/test/FileSystemTestSuite.h @@ -66,6 +66,18 @@ public: TS_ASSERT_EQUALS(FileSystem::fileName("data/FileSystemTestSuite/Settings/player.h"), "player.h"); } + void test_filesystem_extracts_extension() + { + TS_ASSERT_EQUALS(FileSystem::extension("data/FileSystemTestSuite/tictactoe.h"), ".h"); + TS_ASSERT_EQUALS(FileSystem::extension("data/FileSystemTestSuite/tictactoe.cpp"), ".cpp"); + } + + void test_filesystem_extract_filepath_without_extension() + { + TS_ASSERT_EQUALS(FileSystem::filePathWithoutExtension("data/FileSystemTestSuite/tictactoe.h"), "data/FileSystemTestSuite/tictactoe"); + TS_ASSERT_EQUALS(FileSystem::filePathWithoutExtension("data/FileSystemTestSuite/tictactoe.cpp"), "data/FileSystemTestSuite/tictactoe"); + } + private: bool isInVector(const std::vector& files, const std::string filename) {