diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 1eafe428..464923e3 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -1,14 +1,11 @@ #include "Application.h" -#include "utility/file/FileSystem.h" #include "utility/logging/ConsoleLogger.h" #include "utility/logging/FileLogger.h" #include "utility/logging/logging.h" #include "utility/logging/LogManager.h" #include "utility/messaging/MessageQueue.h" -#include "utility/messaging/type/MessageActivateNodes.h" #include "utility/messaging/type/MessageDispatchWhenLicenseValid.h" -#include "utility/messaging/type/MessageScrollSpeedChange.h" #include "utility/messaging/type/MessageStatus.h" #include "utility/messaging/type/MessageShowStartScreen.h" #include "utility/scheduling/TaskScheduler.h" @@ -26,7 +23,6 @@ #include "LicenseChecker.h" #include "settings/ApplicationSettings.h" #include "settings/ColorScheme.h" -#include "settings/ProjectSettings.h" void Application::createInstance( const Version& version, ViewFactory* viewFactory, NetworkFactory* networkFactory @@ -57,7 +53,8 @@ void Application::createInstance( if (networkFactory != nullptr) { - s_instance->m_ideCommunicationController = networkFactory->createIDECommunicationController(s_instance->m_storageCache.get()); + s_instance->m_ideCommunicationController = + networkFactory->createIDECommunicationController(s_instance->m_storageCache.get()); } s_instance->startMessagingAndScheduling(); @@ -224,33 +221,18 @@ void Application::handleMessage(MessageLoadProject* message) return; } - if (message->forceRefresh && !isTrial()) + if (m_project && projectSettingsFilePath == m_project->getProjectSettingsFilePath()) { - if (m_hasGUI) + if (message->forceRefresh) { - std::vector options; - options.push_back("Yes"); - options.push_back("No"); - int result = handleDialog( - "Some settings were changed, the project needs to be fully reindexed. " - "Do you want to reindex the project?", options); - - if (result == 1) - { - if (!m_project || projectSettingsFilePath != m_project->getProjectSettingsFilePath()) - { - createAndLoadProject(projectSettingsFilePath); - return; - } - } + m_project->setStateSettingsUpdated(); + m_project->refresh(false); } - refreshProject(true); - } - else if (!m_project || projectSettingsFilePath != m_project->getProjectSettingsFilePath()) - { - createAndLoadProject(projectSettingsFilePath); + return; } + + createAndLoadProject(projectSettingsFilePath); } void Application::handleMessage(MessageRefresh* message) diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 51b494fb..de628dab 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -2,7 +2,6 @@ #include "component/view/DialogView.h" #include "data/access/StorageAccessProxy.h" -#include "data/graph/Token.h" #include "data/parser/cxx/TaskParseWrapper.h" #include "data/parser/java/TaskParseJava.h" #include "data/PersistentStorage.h" @@ -11,9 +10,8 @@ #include "settings/ProjectSettings.h" #include "utility/file/FileRegister.h" -#include "utility/file/FileSystem.h" -#include "utility/logging/logging.h" #include "utility/messaging/type/MessageFinishedParsing.h" +#include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageStatus.h" #include "utility/scheduling/TaskGroupSequential.h" #include "utility/scheduling/TaskGroupParallel.h" @@ -66,19 +64,81 @@ Project::~Project() bool Project::refresh(bool forceRefresh) { - if (allowsRefresh()) + if (m_state == PROJECT_STATE_NOT_LOADED) { - getProjectSettings()->reload(); + return false; + } - updateFileManager(m_fileManager); + std::string question; - if (buildIndex(forceRefresh)) + if (!forceRefresh) + { + switch (m_state) { - m_state = PROJECT_STATE_LOADED; - return true; + case PROJECT_STATE_EMPTY: + forceRefresh = true; + break; + + case PROJECT_STATE_LOADED: + break; + + case PROJECT_STATE_OUTDATED: + question = + "The project file was changed after the last indexing. The project needs to get fully reindexed to " + "reflect the current project state. Do you want to reindex the project?"; + forceRefresh = true; + break; + + case PROJECT_STATE_OUTVERSIONED: + question = + "This project was indexed with a different version of Coati. It needs to be fully reindexed to be used " + "with this version of Coati. Do you want to reindex the project?"; + forceRefresh = true; + break; + + case PROJECT_STATE_SETTINGS_UPDATED: + question = + "Some settings were changed, the project needs to be fully reindexed. " + "Do you want to reindex the project?"; + forceRefresh = true; + break; + + default: + break; } } + if (forceRefresh && question.size() && Application::getInstance()->hasGUI() && !isTrial()) + { + std::vector options; + options.push_back("Yes"); + options.push_back("No"); + int result = m_dialogView->confirm(question, options); + + if (result == 1) + { + return false; + } + } + + if (!allowsRefresh()) + { + return false; + } + + getProjectSettings()->reload(); + + updateFileManager(m_fileManager); + + if (buildIndex(forceRefresh)) + { + m_storageAccessProxy->setSubject(m_storage.get()); + + m_state = PROJECT_STATE_LOADED; + + return true; + } + return false; } @@ -102,6 +162,14 @@ bool Project::settingsEqualExceptNameAndLocation(const ProjectSettings& otherSet return getProjectSettings()->equalsExceptNameAndLocation(otherSettings); } +void Project::setStateSettingsUpdated() +{ + if (m_state != PROJECT_STATE_NOT_LOADED && m_state != PROJECT_STATE_EMPTY) + { + m_state = PROJECT_STATE_SETTINGS_UPDATED; + } +} + void Project::logStats() const { m_storage->logStats(); @@ -121,105 +189,57 @@ DialogView* Project::getDialogView() const void Project::load() { + m_storageAccessProxy->setSubject(nullptr); + const std::shared_ptr projectSettings = getProjectSettings(); bool loadedSettings = projectSettings->reload(); - if (loadedSettings) + + if (!loadedSettings) { - NameHierarchy::setDelimiter(getSymbolNameDelimiterForLanguage(projectSettings->getLanguage())); - const FilePath projectSettingsPath = projectSettings->getFilePath(); - const FilePath dbPath = FilePath(projectSettingsPath).replaceExtension("coatidb"); - m_storage = std::make_shared(dbPath); + return; + } + + NameHierarchy::setDelimiter(getSymbolNameDelimiterForLanguage(projectSettings->getLanguage())); + + const FilePath projectSettingsPath = projectSettings->getFilePath(); + const FilePath dbPath = FilePath(projectSettingsPath).replaceExtension("coatidb"); + + m_storage = std::make_shared(dbPath); + + if (m_storage->isEmpty()) + { + m_state = PROJECT_STATE_EMPTY; + m_storage->setup(); + } + else if (m_storage->isIncompatible()) + { + m_state = PROJECT_STATE_OUTVERSIONED; + } + else if (TextAccess::createFromFile(projectSettingsPath.str())->getText() != m_storage->getProjectSettingsText()) + { + m_state = PROJECT_STATE_OUTDATED; + } + else + { + m_state = PROJECT_STATE_LOADED; + } + + if (m_state == PROJECT_STATE_LOADED || m_state == PROJECT_STATE_OUTDATED) + { + m_storage->finishParsing(); m_storageAccessProxy->setSubject(m_storage.get()); - if (m_storage->isEmpty()) - { - m_state = PROJECT_STATE_EMPTY; - m_storage->setup(); - } - else if (m_storage->isIncompatible()) - { - m_state = PROJECT_STATE_OUTVERSIONED; - } - else if (TextAccess::createFromFile(projectSettingsPath.str())->getText() != m_storage->getProjectSettingsText()) - { - m_state = PROJECT_STATE_OUTDATED; - } - else - { - m_state = PROJECT_STATE_LOADED; - } - - updateFileManager(m_fileManager); - - bool reparse = false; - - switch (m_state) - { - case PROJECT_STATE_NOT_LOADED: - break; - - case PROJECT_STATE_EMPTY: - buildIndex(false); - m_state = PROJECT_STATE_LOADED; - break; - case PROJECT_STATE_OUTDATED: - if (Application::getInstance()->hasGUI() && !isTrial()) - { - std::vector options; - options.push_back("Yes"); - options.push_back("No"); - int result = Application::getInstance()->handleDialog( - "The project file was changed after the last indexing. The project needs to get fully reindexed to " - "reflect the current project state. Do you want to reindex the project?", options); - - reparse = (result == 0); - } - // dont break here. - case PROJECT_STATE_LOADED: - m_storage->finishParsing(); - MessageFinishedParsing().dispatch(); - MessageStatus("Finished Loading", false, false).dispatch(); - break; - case PROJECT_STATE_OUTVERSIONED: - MessageStatus("Can't load project").dispatch(); - - reparse = true; - - if (Application::getInstance()->hasGUI() && !isTrial()) - { - std::vector options; - options.push_back("Yes"); - options.push_back("No"); - int result = Application::getInstance()->handleDialog( - "This project was indexed with a different version of Coati. It needs to be fully reindexed to be used " - "with this version of Coati. Do you want to reindex the project?", options); - - reparse = (result == 0); - } - m_storage.reset(); - break; - } - - if (reparse) - { - refresh(true); - } + MessageFinishedParsing().dispatch(); + MessageStatus("Finished Loading", false, false).dispatch(); } -} - -void Project::clearStorage() -{ - if (!m_storage) + else { - const FilePath projectSettingsPath = getProjectSettings()->getFilePath(); - const FilePath dbPath = FilePath(projectSettingsPath).replaceExtension("coatidb"); - m_storage = std::make_shared(dbPath); + MessageStatus("Project not loaded", false, false).dispatch(); } - if (m_storage) + if (m_state != PROJECT_STATE_LOADED) { - m_storage->clear(); - m_state = PROJECT_STATE_EMPTY; + MessageRefresh().dispatch(); } } @@ -266,7 +286,7 @@ bool Project::buildIndex(bool forceRefresh) if (forceRefresh) { - clearStorage(); + m_storage->clear(); } m_storage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath().str())->getText()); @@ -309,5 +329,3 @@ bool Project::allowsRefresh() { return true; } - - diff --git a/src/lib/Project.h b/src/lib/Project.h index b2794965..cbb49d76 100644 --- a/src/lib/Project.h +++ b/src/lib/Project.h @@ -7,13 +7,14 @@ #include "utility/file/FileManager.h" #include "data/parser/Parser.h" -#include "settings/ProjectSettings.h" // todo: use forward declaration here -#include "utility/scheduling/Task.h" +#include "settings/LanguageType.h" class DialogView; -class PersistentStorage; -class StorageAccessProxy; class FileRegister; +class PersistentStorage; +class ProjectSettings; +class StorageAccessProxy; +class Task; class Project { @@ -28,7 +29,10 @@ public: FilePath getProjectSettingsFilePath() const; LanguageType getLanguage() const; std::string getDescription() const; + bool settingsEqualExceptNameAndLocation(const ProjectSettings& otherSettings) const; + void setStateSettingsUpdated(); + void logStats() const; protected: @@ -45,13 +49,13 @@ private: PROJECT_STATE_EMPTY, PROJECT_STATE_LOADED, PROJECT_STATE_OUTDATED, - PROJECT_STATE_OUTVERSIONED + PROJECT_STATE_OUTVERSIONED, + PROJECT_STATE_SETTINGS_UPDATED }; Project(const Project&); void load(); - void clearStorage(); bool buildIndex(bool forceRefresh); virtual bool allowsRefresh(); diff --git a/src/lib_gui/qt/element/QtCodeFile.cpp b/src/lib_gui/qt/element/QtCodeFile.cpp index 9b0f10d8..d060be1b 100644 --- a/src/lib_gui/qt/element/QtCodeFile.cpp +++ b/src/lib_gui/qt/element/QtCodeFile.cpp @@ -21,7 +21,6 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeNavigator* navigator) : QFrame() - , m_updateTitleBarFunctor(std::bind(&QtCodeFile::doUpdateTitleBar, this)) , m_navigator(navigator) , m_filePath(filePath) , m_contentRequested(false) @@ -403,6 +402,27 @@ void QtCodeFile::updateSnippets() m_snippets.back()->setProperty("isLast", true); } +void QtCodeFile::updateTitleBar() +{ + if (isTrial()) + { + return; + } + + // cannot use m_filePath.exists() here since it is only checked when FilePath is constructed. + if ((!FileSystem::exists(m_filePath.str())) || + (FileSystem::getLastWriteTime(m_filePath) > m_modificationTime)) + { + m_title->setText(QString(m_filePath.fileName().c_str()) + "*"); + m_title->setToolTip(QString::fromStdString("out of date: " + m_filePath.str())); + } + else + { + m_title->setText(m_filePath.fileName().c_str()); + m_title->setToolTip(QString::fromStdString(m_filePath.str())); + } +} + void QtCodeFile::clickedMinimizeButton() const { MessageChangeFileView( @@ -459,11 +479,6 @@ void QtCodeFile::editProject() MessageProjectEdit().dispatch(); } -void QtCodeFile::handleMessage(MessageWindowFocus* message) -{ - updateTitleBar(); -} - void QtCodeFile::updateRefCount(int refCount) { if (refCount > 0) @@ -488,29 +503,3 @@ void QtCodeFile::updateRefCount(int refCount) m_referenceCount->hide(); } } - -void QtCodeFile::updateTitleBar() -{ - m_updateTitleBarFunctor(); -} - -void QtCodeFile::doUpdateTitleBar() -{ - if (isTrial()) - { - return; - } - - // cannot use m_filePath.exists() here since it is only checked when FilePath is constructed. - if ((!FileSystem::exists(m_filePath.str())) || - (FileSystem::getLastWriteTime(m_filePath) > m_modificationTime)) - { - m_title->setText(QString(m_filePath.fileName().c_str()) + "*"); - m_title->setToolTip(QString::fromStdString("out of date: " + m_filePath.str())); - } - else - { - m_title->setText(m_filePath.fileName().c_str()); - m_title->setToolTip(QString::fromStdString(m_filePath.str())); - } -} diff --git a/src/lib_gui/qt/element/QtCodeFile.h b/src/lib_gui/qt/element/QtCodeFile.h index 37975257..e21cdbb4 100644 --- a/src/lib_gui/qt/element/QtCodeFile.h +++ b/src/lib_gui/qt/element/QtCodeFile.h @@ -10,9 +10,6 @@ #include "utility/file/FilePath.h" #include "utility/TimePoint.h" #include "utility/types.h" -#include "utility/messaging/MessageListener.h" -#include "utility/messaging/type/MessageWindowFocus.h" -#include "qt/utility/QtThreadedFunctor.h" #include "data/ErrorInfo.h" #include "component/view/helper/CodeSnippetParams.h" @@ -26,7 +23,6 @@ class TokenLocationFile; class QtCodeFile : public QFrame - , MessageListener { Q_OBJECT @@ -59,6 +55,7 @@ public: bool hasSnippets() const; void updateSnippets(); + void updateTitleBar(); public slots: void clickedMinimizeButton() const; @@ -71,13 +68,7 @@ private slots: void editProject(); private: - virtual void handleMessage(MessageWindowFocus* message); - void updateRefCount(int refCount); - void updateTitleBar(); - void doUpdateTitleBar(); - - QtThreadedFunctor<> m_updateTitleBarFunctor; QtCodeNavigator* m_navigator; diff --git a/src/lib_gui/qt/element/QtCodeFileList.cpp b/src/lib_gui/qt/element/QtCodeFileList.cpp index 90358172..aa2d3d32 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.cpp +++ b/src/lib_gui/qt/element/QtCodeFileList.cpp @@ -93,6 +93,14 @@ void QtCodeFileList::showContents() } } +void QtCodeFileList::onWindowFocus() +{ + for (std::shared_ptr filePtr : m_files) + { + filePtr->updateTitleBar(); + } +} + QtCodeFile* QtCodeFileList::getFile(const FilePath filePath) { QtCodeFile* file = nullptr; diff --git a/src/lib_gui/qt/element/QtCodeFileList.h b/src/lib_gui/qt/element/QtCodeFileList.h index 9ddeeab1..8ab88445 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.h +++ b/src/lib_gui/qt/element/QtCodeFileList.h @@ -41,6 +41,8 @@ public: void updateFiles(); void showContents(); + void onWindowFocus(); + QtCodeFile* getFile(const FilePath filePath); private: diff --git a/src/lib_gui/qt/element/QtCodeNavigator.cpp b/src/lib_gui/qt/element/QtCodeNavigator.cpp index 59f0bc2b..b361f695 100644 --- a/src/lib_gui/qt/element/QtCodeNavigator.cpp +++ b/src/lib_gui/qt/element/QtCodeNavigator.cpp @@ -20,7 +20,6 @@ QtCodeNavigator::QtCodeNavigator(QWidget* parent) : QWidget(parent) - , m_switchReferenceFunctor(std::bind(&QtCodeNavigator::doSwitchReference, this, std::placeholders::_1)) , m_value(0) , m_refIndex(0) , m_scrollToFile(nullptr) @@ -602,17 +601,29 @@ void QtCodeNavigator::ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF r void QtCodeNavigator::handleMessage(MessageCodeReference* message) { - m_switchReferenceFunctor(message->type); + MessageCodeReference::ReferenceType type = message->type; + + m_onQtThread( + [=]() + { + if (type == MessageCodeReference::REFERENCE_PREVIOUS) + { + previousReference(); + } + else if (type == MessageCodeReference::REFERENCE_NEXT) + { + nextReference(); + } + } + ); } -void QtCodeNavigator::doSwitchReference(MessageCodeReference::ReferenceType type) +void QtCodeNavigator::handleMessage(MessageWindowFocus* message) { - if (type == MessageCodeReference::REFERENCE_PREVIOUS) - { - previousReference(); - } - else if (type == MessageCodeReference::REFERENCE_NEXT) - { - nextReference(); - } + m_onQtThread( + [=]() + { + m_list->onWindowFocus(); + } + ); } diff --git a/src/lib_gui/qt/element/QtCodeNavigator.h b/src/lib_gui/qt/element/QtCodeNavigator.h index a8519ef9..49e029e3 100644 --- a/src/lib_gui/qt/element/QtCodeNavigator.h +++ b/src/lib_gui/qt/element/QtCodeNavigator.h @@ -9,6 +9,7 @@ #include "qt/utility/QtThreadedFunctor.h" #include "utility/messaging/MessageListener.h" #include "utility/messaging/type/MessageCodeReference.h" +#include "utility/messaging/type/MessageWindowFocus.h" class QLabel; class QPushButton; @@ -18,6 +19,7 @@ class TokenLocationFile; class QtCodeNavigator : public QWidget , public MessageListener + , public MessageListener { Q_OBJECT @@ -99,9 +101,9 @@ private: void ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect); void handleMessage(MessageCodeReference* message); - void doSwitchReference(MessageCodeReference::ReferenceType type); + void handleMessage(MessageWindowFocus* message); - QtThreadedFunctor m_switchReferenceFunctor; + QtThreadedLambdaFunctor m_onQtThread; QScrollArea* m_scrollArea; QtCodeFileList* m_list; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 663a50bb..859ca4d0 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -15,7 +15,7 @@ add_files( FileSystemTestSuite.h GeneratorTestSuite.h GraphTestSuite.h - JavaParserTestSuite.h +# JavaParserTestSuite.h LogManagerTestSuite.h MatrixBaseTestSuite.h MessageQueueTestSuite.h