From 5868fe4d398407a55be1406faa211b5ac8c6f31b Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Tue, 19 May 2015 16:27:42 +0200 Subject: [PATCH] ui: minimize and maximize buttons for QtCodeFile This change switches the code view UI to use minimize and maximize buttons within the QtCodeView instead of creating separate windows for each maximized code file. Real icons for the buttons are still missing. --- bin/app/data/gui/code_view/code_view.css | 17 ++- src/app/qt/element/QtCodeFile.cpp | 118 +++++++++++++++++- src/app/qt/element/QtCodeFile.h | 8 ++ src/app/qt/view/QtCodeView.cpp | 51 +------- src/app/qt/view/QtCodeView.h | 2 - src/lib/CMakeLists.txt | 3 +- .../component/controller/CodeController.cpp | 17 ++- src/lib/component/controller/CodeController.h | 3 + src/lib/data/Storage.cpp | 43 +++++-- src/lib/data/Storage.h | 2 + src/lib/data/access/StorageAccess.h | 2 + src/lib/data/access/StorageAccessProxy.cpp | 10 ++ src/lib/data/access/StorageAccessProxy.h | 1 + .../messaging/type/MessageActivateFile.h | 23 ++++ 14 files changed, 223 insertions(+), 77 deletions(-) create mode 100644 src/lib/utility/messaging/type/MessageActivateFile.h diff --git a/bin/app/data/gui/code_view/code_view.css b/bin/app/data/gui/code_view/code_view.css index 9ca89eb7..803b066f 100644 --- a/bin/app/data/gui/code_view/code_view.css +++ b/bin/app/data/gui/code_view/code_view.css @@ -36,14 +36,25 @@ font-size: 14px; } -#code_area #maximize_button { - border: none; +#code_file #maximize_button { + background-color: lightgray; border-image: none; - margin: 5px; + border-radius: 8px; + margin: 1px; max-height: 16px; max-width: 16px; } +#code_file #maximize_button:enabled { + border-image: url(data/gui/code_view/images/button_maximize.png); +} + +#code_area #maximize_button { + background-color: none; + border-image: none; + margin: 5px; +} + #code_area #maximize_button:enabled { border-image: url(data/gui/code_view/images/button_maximize.png); } diff --git a/src/app/qt/element/QtCodeFile.cpp b/src/app/qt/element/QtCodeFile.cpp index 6540e39c..214b6751 100644 --- a/src/app/qt/element/QtCodeFile.cpp +++ b/src/app/qt/element/QtCodeFile.cpp @@ -3,8 +3,10 @@ #include #include +#include "utility/messaging/type/MessageActivateFile.h" #include "utility/messaging/type/MessageShowFile.h" +#include "data/location/TokenLocationFile.h" #include "qt/element/QtCodeFileList.h" #include "qt/element/QtCodeSnippet.h" @@ -21,6 +23,12 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent) layout->setAlignment(Qt::AlignTop); setLayout(layout); + QHBoxLayout* titleLayout = new QHBoxLayout(); + titleLayout->setMargin(0); + titleLayout->setSpacing(0); + titleLayout->setAlignment(Qt::AlignLeft); + layout->addLayout(titleLayout); + m_title = new QPushButton(filePath.fileName().c_str(), this); m_title->setObjectName("title_label"); m_title->minimumSizeHint(); // force font loading @@ -28,9 +36,33 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent) m_title->setToolTip(QString::fromStdString(filePath.str())); m_title->setFixedWidth(m_title->fontMetrics().width(filePath.fileName().c_str()) + 32); m_title->setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed); - layout->addWidget(m_title); + titleLayout->addWidget(m_title); + + titleLayout->addStretch(3); + + m_minimizeButton = new QPushButton(this); + m_minimizeButton->setObjectName("maximize_button"); + m_minimizeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + titleLayout->addWidget(m_minimizeButton); + + m_snippetButton = new QPushButton(this); + m_snippetButton->setObjectName("maximize_button"); + m_snippetButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + titleLayout->addWidget(m_snippetButton); + + m_maximizeButton = new QPushButton(this); + m_maximizeButton->setObjectName("maximize_button"); + m_maximizeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + titleLayout->addWidget(m_maximizeButton); + + m_minimizeButton->setEnabled(false); + m_snippetButton->setEnabled(false); + m_maximizeButton->setEnabled(false); connect(m_title, SIGNAL(clicked()), this, SLOT(clickedTitle())); + connect(m_minimizeButton, SIGNAL(clicked()), this, SLOT(clickedMinimizeButton())); + connect(m_snippetButton, SIGNAL(clicked()), this, SLOT(clickedSnippetButton())); + connect(m_maximizeButton, SIGNAL(clicked()), this, SLOT(clickedMaximizeButton())); update(); } @@ -73,14 +105,22 @@ void QtCodeFile::addCodeSnippet( std::shared_ptr snippet( new QtCodeSnippet(startLineNumber, title, code, locationFile, this)); + layout()->addWidget(snippet.get()); + + if (locationFile->isWholeCopy) + { + m_fileSnippet = snippet; + clickedMaximizeButton(); + return; + } + + m_snippets.push_back(snippet); + if (m_parent->getShowMaximizeButton()) { snippet->addMaximizeButton(); } - layout()->addWidget(snippet.get()); - m_snippets.push_back(snippet); - int maxDigits = 1; for (std::shared_ptr snippet : m_snippets) { @@ -91,6 +131,8 @@ void QtCodeFile::addCodeSnippet( { snippet->updateLineNumberAreaWidthForDigits(maxDigits); } + + clickedSnippetButton(); } void QtCodeFile::updateContent() @@ -100,10 +142,76 @@ void QtCodeFile::updateContent() snippet->updateContent(); } + if (m_fileSnippet) + { + m_fileSnippet->updateContent(); + } + m_title->setEnabled(m_parent->getShowMaximizeButton()); } void QtCodeFile::clickedTitle() { - MessageShowFile(m_filePath.absoluteStr(), 0, 0).dispatch(); + MessageActivateFile(m_filePath).dispatch(); +} + +void QtCodeFile::clickedMinimizeButton() +{ + for (std::shared_ptr snippet : m_snippets) + { + snippet->hide(); + } + + if (m_fileSnippet) + { + m_fileSnippet->hide(); + } + + m_minimizeButton->setEnabled(false); + if (m_snippets.size()) + { + m_snippetButton->setEnabled(true); + } + m_maximizeButton->setEnabled(true); +} + +void QtCodeFile::clickedSnippetButton() +{ + for (std::shared_ptr snippet : m_snippets) + { + snippet->show(); + } + + if (m_fileSnippet) + { + m_fileSnippet->hide(); + } + + m_minimizeButton->setEnabled(true); + m_snippetButton->setEnabled(false); + m_maximizeButton->setEnabled(true); +} + +void QtCodeFile::clickedMaximizeButton() +{ + for (std::shared_ptr snippet : m_snippets) + { + snippet->hide(); + } + + if (m_fileSnippet) + { + m_fileSnippet->show(); + } + else + { + MessageShowFile(m_filePath.absoluteStr(), 0, 0).dispatch(); + } + + m_minimizeButton->setEnabled(true); + if (m_snippets.size()) + { + m_snippetButton->setEnabled(true); + } + m_maximizeButton->setEnabled(false); } diff --git a/src/app/qt/element/QtCodeFile.h b/src/app/qt/element/QtCodeFile.h index f388b535..5e6730e2 100644 --- a/src/app/qt/element/QtCodeFile.h +++ b/src/app/qt/element/QtCodeFile.h @@ -41,13 +41,21 @@ public: private slots: void clickedTitle(); + void clickedMinimizeButton(); + void clickedSnippetButton(); + void clickedMaximizeButton(); private: QtCodeFileList* m_parent; QPushButton* m_title; + QPushButton* m_minimizeButton; + QPushButton* m_snippetButton; + QPushButton* m_maximizeButton; std::vector> m_snippets; + std::shared_ptr m_fileSnippet; + const FilePath m_filePath; }; diff --git a/src/app/qt/view/QtCodeView.cpp b/src/app/qt/view/QtCodeView.cpp index 3bd76993..b826056b 100644 --- a/src/app/qt/view/QtCodeView.cpp +++ b/src/app/qt/view/QtCodeView.cpp @@ -1,7 +1,5 @@ #include "qt/view/QtCodeView.h" -#include - #include "qt/element/QtCodeFileList.h" #include "qt/view/QtViewWidgetWrapper.h" #include "utility/file/FileSystem.h" @@ -60,32 +58,12 @@ void QtCodeView::showCodeFile(const CodeSnippetParams& params) void QtCodeView::doRefreshView() { setStyleSheet(m_widget); - - clearClosedWindows(); - for (std::shared_ptr window: m_windows) - { - setStyleSheet(window.get()); - } } void QtCodeView::doShowCodeSnippets(const std::vector& snippets) { m_widget->clearCodeSnippets(); - clearClosedWindows(); - for (std::shared_ptr window: m_windows) - { - if (m_errorMessages.size()) - { - window->close(); - } - else - { - window->setActiveTokenIds(m_activeTokenIds); - window->setErrorMessages(m_errorMessages); - } - } - m_widget->setActiveTokenIds(m_activeTokenIds); m_widget->setErrorMessages(m_errorMessages); m_widget->setShowMaximizeButton(m_errorMessages.size() == 0); @@ -98,22 +76,7 @@ void QtCodeView::doShowCodeSnippets(const std::vector& snippe void QtCodeView::doShowCodeFile(const CodeSnippetParams& params) { - std::shared_ptr ptr = createQtCodeFileList(); - m_windows.push_back(ptr); - - ptr->setShowMaximizeButton(false); - ptr->setActiveTokenIds(m_activeTokenIds); - ptr->setErrorMessages(m_errorMessages); - ptr->addCodeSnippet(1, params.title, params.code, params.locationFile); - - ptr->setWindowTitle(params.locationFile->getFilePath().fileName().c_str()); - ptr->show(); - - float percent = float(params.startLineNumber + params.endLineNumber) / float(params.lineCount) / 2; - float min = ptr->verticalScrollBar()->minimum(); - float max = ptr->verticalScrollBar()->maximum(); - - ptr->verticalScrollBar()->setValue(min + (max - min) * percent); + m_widget->addCodeSnippet(1, params.title, params.code, params.locationFile); } std::shared_ptr QtCodeView::createQtCodeFileList() const @@ -128,18 +91,6 @@ void QtCodeView::setStyleSheet(QWidget* widget) const widget->setStyleSheet(TextAccess::createFromFile("data/gui/code_view/code_view.css")->getText().c_str()); } -void QtCodeView::clearClosedWindows() -{ - for (size_t i = 0; i < m_windows.size(); i++) - { - if (!m_windows[i]->isVisible()) - { - m_windows.erase(m_windows.begin() + i); - i--; - } - } -} - void QtCodeView::focusToken(const Id tokenId) { m_focusTokenFunctor(tokenId); diff --git a/src/app/qt/view/QtCodeView.h b/src/app/qt/view/QtCodeView.h index 647a873e..ed1ab423 100644 --- a/src/app/qt/view/QtCodeView.h +++ b/src/app/qt/view/QtCodeView.h @@ -43,7 +43,6 @@ private: std::shared_ptr createQtCodeFileList() const; void setStyleSheet(QWidget* widget) const; - void clearClosedWindows(); QtThreadedFunctor<> m_refreshViewFunctor; QtThreadedFunctor&> m_showCodeSnippetsFunctor; @@ -52,7 +51,6 @@ private: QtThreadedFunctor<> m_defocusTokenFunctor; QtCodeFileList* m_widget; - std::vector> m_windows; std::vector m_activeTokenIds; std::vector m_errorMessages; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 496f43c5..550543e5 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -9,7 +9,7 @@ add_files( data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h data/parser/cxx/name_resolver/CxxTypeNameResolver.cpp data/parser/cxx/name_resolver/CxxTypeNameResolver.h - + data/parser/cxx/ASTAction.cpp data/parser/cxx/ASTAction.h data/parser/cxx/ASTActionFactory.cpp @@ -248,6 +248,7 @@ add_files( utility/math/Vector4.h utility/math/VectorBase.h + utility/messaging/type/MessageActivateFile.h utility/messaging/type/MessageActivateTokenLocation.h utility/messaging/type/MessageActivateTokens.h utility/messaging/type/MessageAutoRefreshChanged.h diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index bef599e5..25060453 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -23,6 +23,11 @@ CodeController::~CodeController() const uint CodeController::s_lineRadius = 2; +void CodeController::handleMessage(MessageActivateFile* message) +{ + MessageActivateTokens(std::vector(1, m_storageAccess->getTokenIdForFileNode(message->filePath))).dispatch(); +} + void CodeController::handleMessage(MessageActivateTokenLocation* message) { if (message->locationId) @@ -140,10 +145,13 @@ std::vector CodeController::getSnippetsForActiveTok { std::vector fileSnippets = getSnippetsForFile(file); - for (CodeView::CodeSnippetParams& params : fileSnippets) + if (!file->isWholeCopy) { - params.locationFile = m_storageAccess->getTokenLocationsForLinesInFile( - file->getFilePath().str(), params.startLineNumber, params.endLineNumber); + for (CodeView::CodeSnippetParams& params : fileSnippets) + { + params.locationFile = m_storageAccess->getTokenLocationsForLinesInFile( + file->getFilePath().str(), params.startLineNumber, params.endLineNumber); + } } if (declarationId != 0) @@ -214,7 +222,8 @@ std::vector CodeController::getSnippetsForFile(std: params.endLineNumber = std::min(textAccess->getLineCount(), range.end.row + (range.end.strong ? 0 : snippetExpandRange)); - std::shared_ptr tempFile = m_storageAccess->getTokenLocationsForLinesInFile(file->getFilePath().str(), params.startLineNumber, params.endLineNumber); + std::shared_ptr tempFile = + m_storageAccess->getTokenLocationsForLinesInFile(file->getFilePath().str(), params.startLineNumber, params.endLineNumber); TokenLocationLine* firstUsedLine = nullptr; for (size_t i = params.startLineNumber; i <= params.endLineNumber && firstUsedLine == nullptr; i++) { diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index faaaf50c..afd87fa8 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -5,6 +5,7 @@ #include #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/MessageActivateFile.h" #include "utility/messaging/type/MessageActivateTokenLocation.h" #include "utility/messaging/type/MessageActivateTokens.h" #include "utility/messaging/type/MessageFinishedParsing.h" @@ -24,6 +25,7 @@ class TokenLocationFile; class CodeController : public Controller + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -39,6 +41,7 @@ public: private: static const uint s_lineRadius; + virtual void handleMessage(MessageActivateFile* message); virtual void handleMessage(MessageActivateTokenLocation* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageFinishedParsing* message); diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 6ccea078..83a5130f 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -109,18 +109,7 @@ std::set Storage::getDependingFilePathsAndRemoveFileNodes(const std::s for (const FilePath& filePath : filePaths) { - SearchNode* searchNode = m_tokenIndex.getNode(filePath.fileName()); - if (!searchNode || searchNode->getTokenIds().size() != 1) - { - continue; - } - - Node* fileNode = m_graph.getNodeById(searchNode->getFirstTokenId()); - if (!fileNode->isType(Node::NODE_FILE)) - { - LOG_ERROR("Node is not of type file."); - continue; - } + Node* fileNode = findFileNode(filePath); if (!fileNode->getComponent() || fileNode->getComponent()->getFilePath() != filePath) @@ -956,6 +945,17 @@ std::vector Storage::getTokenIdsForQuery(std::string query) const return outGraph.getTokenIds(); } +Id Storage::getTokenIdForFileNode(const FilePath& filePath) const +{ + Node* fileNode = findFileNode(filePath); + if (fileNode) + { + return fileNode->getId(); + } + + return 0; +} + TokenLocationCollection Storage::getTokenLocationsForTokenIds(const std::vector& tokenIds) const { TokenLocationCollection ret; @@ -1006,6 +1006,7 @@ std::shared_ptr Storage::getTokenLocationsForFile(const std:: ret->addTokenLocationAsPlainCopy(tokenLocation); } ); + ret->isWholeCopy = true; return ret; } @@ -1165,6 +1166,24 @@ Node* Storage::addFileNode(const FilePath& filePath) return fileNode; } +Node* Storage::findFileNode(const FilePath& filePath) const +{ + SearchNode* searchNode = m_tokenIndex.getNode(filePath.fileName()); + if (!searchNode || searchNode->getTokenIds().size() != 1) + { + return nullptr; + } + + Node* fileNode = m_graph.getNodeById(searchNode->getFirstTokenId()); + if (!fileNode->isType(Node::NODE_FILE)) + { + LOG_ERROR("Node is not of type file."); + return nullptr; + } + + return fileNode; +} + TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const { switch (access) diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index c59ddecf..e6ced56a 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -119,6 +119,7 @@ public: virtual std::vector getActiveTokenIdsForLocationId(Id locationId) const; virtual std::vector getTokenIdsForQuery(std::string query) const; + virtual Id getTokenIdForFileNode(const FilePath& filePath) const; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const; virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const; @@ -140,6 +141,7 @@ private: Node* addNodeHierarchyWithDistinctSignature(Node::NodeType type, const ParseFunction& function); Node* addFileNode(const FilePath& filePath); + Node* findFileNode(const FilePath& filePath) const; TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const; TokenComponentAccess* addAccess(Node* node, ParserClient::AccessType access); diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 10a00a6e..8c5095c3 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -6,6 +6,7 @@ #include #include "utility/types.h" +#include "utility/file/FilePath.h" #include "data/graph/Node.h" #include "data/search/SearchMatch.h" @@ -32,6 +33,7 @@ public: virtual std::vector getActiveTokenIdsForLocationId(Id locationId) const = 0; virtual std::vector getTokenIdsForQuery(std::string query) const = 0; + virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const = 0; virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index ef38f80c..d240d9ef 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -112,6 +112,16 @@ std::vector StorageAccessProxy::getTokenIdsForQuery(std::string query) const return std::vector(); } +Id StorageAccessProxy::getTokenIdForFileNode(const FilePath& filePath) const +{ + if (hasSubject()) + { + return m_subject->getTokenIdForFileNode(filePath); + } + + return 0; +} + TokenLocationCollection StorageAccessProxy::getTokenLocationsForTokenIds(const std::vector& tokenIds) const { if (hasSubject()) diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index 1de7324e..c5d0074a 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -25,6 +25,7 @@ public: virtual std::vector getActiveTokenIdsForLocationId(Id locationId) const; virtual std::vector getTokenIdsForQuery(std::string query) const; + virtual Id getTokenIdForFileNode(const FilePath& filePath) const; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const; virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const; diff --git a/src/lib/utility/messaging/type/MessageActivateFile.h b/src/lib/utility/messaging/type/MessageActivateFile.h new file mode 100644 index 00000000..ec67c82b --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateFile.h @@ -0,0 +1,23 @@ +#ifndef MESSAGE_ACTIVATE_FILE_H +#define MESSAGE_ACTIVATE_FILE_H + +#include "utility/messaging/Message.h" +#include "utility/file/FilePath.h" + +class MessageActivateFile: public Message +{ +public: + MessageActivateFile(const FilePath& filePath) + : filePath(filePath) + { + } + + static const std::string getStaticType() + { + return "MessageActivateFile"; + } + + const FilePath filePath; +}; + +#endif // MESSAGE_ACTIVATE_FILE_H