diff --git a/CMakeLists.txt b/CMakeLists.txt index b2a7e181..6fd364ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,6 +481,24 @@ create_source_groups(${TRIAL_FILES}) target_link_libraries(${TRIAL_PROJECT_NAME} ${LIB_GUI_PROJECT_NAME} ${LIB_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME} ) +if (WIN32) + SET_TARGET_PROPERTIES( + ${TRIAL_PROJECT_NAME} PROPERTIES + LINK_FLAGS "/DELAYLOAD:jvm.dll" + ) +elseif (APPLE) + set(LAZY_LIB_FLAGS2 "") + + foreach (_lib ${JNI_LIBRARIES}) + set (LAZY_LIB_FLAGS2 "${LAZY_LIB_FLAGS2} -lazy_library ${_lib}") + endforeach() + + SET_TARGET_PROPERTIES( + ${TRIAL_PROJECT_NAME} PROPERTIES + LINK_FLAGS ${LAZY_LIB_FLAGS2} + ) +endif() + if(UNIX AND NOT APPLE) target_link_libraries(${TRIAL_PROJECT_NAME} pthread dl rt) endif() @@ -614,7 +632,11 @@ add_executable (${TEST_PROJECT_NAME} ${TESTGEN_FILE} ${TEST_FILES} ) create_source_groups(${TEST_FILES}) -target_link_libraries(${TEST_PROJECT_NAME} ${LIB_PARSER_PROJECT_NAME} ${LIB_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME}) +if (WIN32) + target_link_libraries(${TEST_PROJECT_NAME} ${LIB_PARSER_PROJECT_NAME} ${LIB_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME}) +else() + target_link_libraries(${TEST_PROJECT_NAME} ${LIB_PARSER_PROJECT_NAME} ${LIB_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME} ${JNI_LIBRARIES}) +endif() if (WIN32) SET_TARGET_PROPERTIES( diff --git a/bin/app/data/gui/indexing_dialog/error.png b/bin/app/data/gui/indexing_dialog/error.png new file mode 100644 index 00000000..4f7f1cfc Binary files /dev/null and b/bin/app/data/gui/indexing_dialog/error.png differ diff --git a/bin/app/data/gui/indexing_dialog/flag.png b/bin/app/data/gui/indexing_dialog/flag.png new file mode 100644 index 00000000..4fb1bef9 Binary files /dev/null and b/bin/app/data/gui/indexing_dialog/flag.png differ diff --git a/bin/app/data/gui/indexing_dialog/indexing_dialog.css b/bin/app/data/gui/indexing_dialog/indexing_dialog.css new file mode 100644 index 00000000..92585737 --- /dev/null +++ b/bin/app/data/gui/indexing_dialog/indexing_dialog.css @@ -0,0 +1,56 @@ +* { + color: white; +} + +#topHalf { + background: #007AC2; + border-top-left-radius: 15px; + border-top-right-radius: 15px; +} + +#title { + color: white; + font-size: 24pt; + font-weight: bold; +} + +#percent { + font-size: 24pt; + font-weight: bold; +} + +#message { + font-size: 16pt; + font-weight: bold; +} + +#filePath { + font-size: 12pt; +} + +#errorCount { + font-size: 14pt; + border: none; + background: transparent; +} + +#windowButton { + background: transparent; + border: 1px solid white; + color: white; +} + +#windowButton:hover { + background: transparent; + border: 1px solid white; + color: white; +} + +#windowButton:hover { + color: #2E3C86; + background: white; +} + +#windowButton:default { + border: 2px solid white; +} diff --git a/bin/app/data/gui/indexing_dialog/progress_bar_element.png b/bin/app/data/gui/indexing_dialog/progress_bar_element.png new file mode 100644 index 00000000..870d7132 Binary files /dev/null and b/bin/app/data/gui/indexing_dialog/progress_bar_element.png differ diff --git a/bin/app/data/gui/window/window.css b/bin/app/data/gui/window/window.css index 8880d449..021f45b7 100644 --- a/bin/app/data/gui/window/window.css +++ b/bin/app/data/gui/window/window.css @@ -1,5 +1,6 @@ * { font-size: 12pt; + font-family: "Roboto"; } #title { @@ -40,19 +41,19 @@ } #formArea { - background: white; + background: transparent; border: none; } #scrollArea { - background: white; + background: transparent; border: none; border-top: 1px solid lightgrey; border-bottom: 1px solid lightgrey; } #form { - background: white; + background: transparent; } #helpButton, #dotsButton, #refreshButton { @@ -128,7 +129,11 @@ #windowButton:hover { color: white; - background: #2D3F85; + background: #2D3C86; +} + +#windowButton:default { + border: 2px solid lightgray; } #menuButton:hover, #menuButton:checked { diff --git a/src/app/data/parser/cxx/TaskParseCxx.cpp b/src/app/data/parser/cxx/TaskParseCxx.cpp index 5cb406f8..e08f06e2 100644 --- a/src/app/data/parser/cxx/TaskParseCxx.cpp +++ b/src/app/data/parser/cxx/TaskParseCxx.cpp @@ -4,11 +4,10 @@ #include "clang/Tooling/JSONCompilationDatabase.h" +#include "component/view/DialogView.h" #include "data/parser/cxx/CxxParser.h" #include "data/PersistentStorage.h" #include "utility/file/FileRegister.h" -#include "utility/messaging/type/MessageFinishedParsing.h" -#include "utility/messaging/type/MessageStatus.h" #include "utility/utility.h" std::vector TaskParseCxx::getSourceFilesFromCDB(const FilePath& compilationDatabasePath) @@ -30,11 +29,13 @@ TaskParseCxx::TaskParseCxx( PersistentStorage* storage, std::shared_ptr storageMutex, std::shared_ptr fileRegister, - const Parser::Arguments& arguments + const Parser::Arguments& arguments, + DialogView* dialogView ) : m_storage(storage) , m_storageMutex(storageMutex) , m_arguments(arguments) + , m_dialogView(dialogView) , m_isCDB(false) { if (arguments.compilationDatabasePath.exists()) @@ -72,12 +73,8 @@ Task::TaskState TaskParseCxx::update() return Task::STATE_FINISHED; } - std::stringstream ss; - ss << "indexing files (ESC to quit): ["; - ss << fileRegister->getParsedSourceFilesCount() << "/"; - ss << fileRegister->getSourceFilesCount() << "] "; - ss << sourcePath.str(); - MessageStatus(ss.str(), false, true).dispatch(); + m_dialogView->updateIndexingDialog( + fileRegister->getParsedSourceFilesCount(), fileRegister->getSourceFilesCount(), sourcePath.str()); std::shared_ptr intermediateStorage = std::make_shared(); @@ -121,3 +118,7 @@ void TaskParseCxx::interrupt() void TaskParseCxx::revert() { } + +void TaskParseCxx::abort() +{ +} diff --git a/src/app/data/parser/cxx/TaskParseWrapper.cpp b/src/app/data/parser/cxx/TaskParseWrapper.cpp index 998269d6..e98e762b 100644 --- a/src/app/data/parser/cxx/TaskParseWrapper.cpp +++ b/src/app/data/parser/cxx/TaskParseWrapper.cpp @@ -1,17 +1,19 @@ #include "data/parser/cxx/TaskParseWrapper.h" +#include "component/view/DialogView.h" #include "data/PersistentStorage.h" #include "utility/file/FileRegister.h" #include "utility/messaging/type/MessageFinishedParsing.h" -#include "utility/messaging/type/MessageStatus.h" #include "utility/utility.h" TaskParseWrapper::TaskParseWrapper( PersistentStorage* storage, - std::shared_ptr fileRegister + std::shared_ptr fileRegister, + DialogView* dialogView ) : m_storage(storage) , m_fileRegister(fileRegister) + , m_dialogView(dialogView) { } @@ -21,6 +23,8 @@ TaskParseWrapper::~TaskParseWrapper() void TaskParseWrapper::enter() { + m_dialogView->updateIndexingDialog(0, m_fileRegister->getSourceFilesCount(), ""); + m_start = utility::durationStart(); m_storage->startParsing(); @@ -36,24 +40,28 @@ void TaskParseWrapper::exit() { m_task->exit(); - MessageStatus("optimizing database", false, true).dispatch(); + m_dialogView->showProgressDialog("Finish Indexing", "Optimizing database"); m_storage->optimizeMemory(); - MessageStatus("building caches", false, true).dispatch(); + m_dialogView->showProgressDialog("Finish Indexing", "Building caches"); m_storage->finishParsing(); - MessageFinishedParsing( + m_dialogView->hideProgressDialog(); + + MessageFinishedParsing().dispatch(); + + m_dialogView->finishedIndexingDialog( m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), - utility::duration(m_start) - ).dispatch(); + utility::duration(m_start), + m_storage->getErrorCount() + ); } void TaskParseWrapper::interrupt() { - MessageStatus("indexing files interrupted", false, true).dispatch(); m_task->interrupt(); } @@ -61,3 +69,17 @@ void TaskParseWrapper::revert() { m_task->revert(); } + +void TaskParseWrapper::abort() +{ + m_task->abort(); + + MessageFinishedParsing().dispatch(); + + m_dialogView->finishedIndexingDialog( + m_fileRegister->getParsedSourceFilesCount(), + m_fileRegister->getSourceFilesCount(), + 0, + m_storage->getErrorCount() + ); +} diff --git a/src/app/data/parser/java/TaskParseJava.cpp b/src/app/data/parser/java/TaskParseJava.cpp index 63a2e998..6e09cf56 100644 --- a/src/app/data/parser/java/TaskParseJava.cpp +++ b/src/app/data/parser/java/TaskParseJava.cpp @@ -1,11 +1,11 @@ #include "data/parser/java/TaskParseJava.h" +#include "component/view/DialogView.h" #include "data/parser/java/JavaParser.h" #include "data/parser/ParserClientImpl.h" #include "data/PersistentStorage.h" #include "utility/file/FileRegister.h" #include "utility/messaging/type/MessageFinishedParsing.h" -#include "utility/messaging/type/MessageStatus.h" #include "utility/text/TextAccess.h" #include "utility/utility.h" @@ -13,12 +13,14 @@ TaskParseJava::TaskParseJava( PersistentStorage* storage, std::shared_ptr storageMutex, std::shared_ptr fileRegister, - const Parser::Arguments& arguments + const Parser::Arguments& arguments, + DialogView* dialogView ) : m_storage(storage) , m_storageMutex(storageMutex) , m_fileRegister(fileRegister) , m_arguments(arguments) + , m_dialogView(dialogView) { } @@ -38,12 +40,8 @@ Task::TaskState TaskParseJava::update() return Task::STATE_FINISHED; } - std::stringstream ss; - ss << "indexing files (ESC to quit): ["; - ss << m_fileRegister->getParsedSourceFilesCount() << "/"; - ss << m_fileRegister->getSourceFilesCount() << "] "; - ss << sourcePath.str(); - MessageStatus(ss.str(), false, true).dispatch(); + m_dialogView->updateIndexingDialog( + m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str()); std::shared_ptr intermediateStorage = std::make_shared(); @@ -76,3 +74,7 @@ void TaskParseJava::interrupt() void TaskParseJava::revert() { } + +void TaskParseJava::abort() +{ +} diff --git a/src/app/main.cpp b/src/app/main.cpp index b917a09a..21053547 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -96,6 +96,7 @@ int main(int argc, char *argv[]) QtNetworkFactory networkFactory; utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf"); + utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".ttf"); Application::createInstance(version, &viewFactory, &networkFactory); ScopedFunctor f([](){ Application::destroyInstance(); diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 34813de8..bd4ec310 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -13,6 +13,7 @@ #include "utility/UserPaths.h" #include "utility/Version.h" +#include "component/view/DialogView.h" #include "component/view/GraphViewStyle.h" #include "component/controller/NetworkFactory.h" #include "component/view/MainView.h" @@ -113,12 +114,12 @@ bool Application::hasGUI() int Application::handleDialog(const std::string& message) { - return m_mainView->confirm(message); + return getDialogView()->confirm(message); } int Application::handleDialog(const std::string& message, const std::vector& options) { - return m_mainView->confirm(message, options); + return getDialogView()->confirm(message, options); } void Application::setTitle(const std::string& title) @@ -135,7 +136,7 @@ void Application::createAndLoadProject(const FilePath& projectSettingsFilePath) m_storageCache->clear(); - m_project = Project::create(projectSettingsFilePath, m_storageCache.get()); + m_project = Project::create(projectSettingsFilePath, m_storageCache.get(), getDialogView()); if (m_project) { @@ -163,21 +164,14 @@ void Application::createAndLoadProject(const FilePath& projectSettingsFilePath) void Application::refreshProject(bool force) { - MessageStatus("Refreshing Project").dispatch(); - - m_storageCache->clear(); - if (m_hasGUI) + bool indexing = m_project->refresh(force); + if (indexing) { - m_componentManager->refreshViews(); - } - - if (force) - { - m_project->forceRefresh(); - } - else - { - m_project->refresh(); + m_storageCache->clear(); + if (m_hasGUI) + { + m_componentManager->refreshViews(); + } } } @@ -217,7 +211,7 @@ void Application::handleMessage(MessageLoadProject* message) std::vector options; options.push_back("Yes"); options.push_back("No"); - int result = m_mainView->confirm( + int result = handleDialog( "Some settings were changed, the project needs to be fully reindexed. " "Do you want to reindex the project?", options); @@ -301,3 +295,14 @@ void Application::updateRecentProjects(const FilePath& projectSettingsFilePath) m_mainView->updateRecentProjectMenu(); } } + +DialogView* Application::getDialogView() const +{ + if (m_componentManager) + { + return m_componentManager->getDialogView(); + } + + static DialogView dialogView; + return &dialogView; +} diff --git a/src/lib/Application.h b/src/lib/Application.h index b2192952..064da00a 100644 --- a/src/lib/Application.h +++ b/src/lib/Application.h @@ -12,12 +12,13 @@ #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageSwitchColorScheme.h" +class DialogView; class IDECommunicationController; -class NetworkFactory; -class ViewFactory; class MainView; +class NetworkFactory; class StorageCache; class Version; +class ViewFactory; class Application : public MessageListener @@ -63,6 +64,8 @@ private: void updateRecentProjects(const FilePath& projectSettingsFilePath); + DialogView* getDialogView() const; + const bool m_hasGUI; std::shared_ptr m_project; std::shared_ptr m_storageCache; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8a11a5b4..fa2b6c41 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -43,6 +43,8 @@ add_files( component/view/CodeView.h component/view/CompositeView.cpp component/view/CompositeView.h + component/view/DialogView.cpp + component/view/DialogView.h component/view/GraphView.cpp component/view/GraphView.h component/view/GraphViewStyle.cpp diff --git a/src/lib/CxxProject.cpp b/src/lib/CxxProject.cpp index a347fc0c..de15a302 100644 --- a/src/lib/CxxProject.cpp +++ b/src/lib/CxxProject.cpp @@ -1,21 +1,15 @@ #include "CxxProject.h" - +#include "data/parser/cxx/TaskParseCxx.h" #include "settings/ApplicationSettings.h" +#include "utility/file/FileRegister.h" +#include "utility/file/FileSystem.h" #include "utility/messaging/type/MessageStatus.h" #include "utility/utility.h" #include "Application.h" -#include "utility/file/FileRegister.h" -#include "utility/file/FileSystem.h" - - -#include "data/parser/cxx/TaskParseCxx.h" - - - CxxProject::~CxxProject() { } @@ -30,8 +24,10 @@ const std::shared_ptr CxxProject::getProjectSettings() const return m_projectSettings; } -CxxProject::CxxProject(std::shared_ptr projectSettings, StorageAccessProxy* storageAccessProxy) - : Project(storageAccessProxy) +CxxProject::CxxProject( + std::shared_ptr projectSettings, StorageAccessProxy* storageAccessProxy, DialogView* dialogView +) + : Project(storageAccessProxy, dialogView) , m_projectSettings(projectSettings) { } @@ -66,7 +62,8 @@ std::shared_ptr CxxProject::createIndexerTask( storage, storageMutex, fileRegister, - getParserArguments() + getParserArguments(), + getDialogView() ); } @@ -128,5 +125,3 @@ Parser::Arguments CxxProject::getParserArguments() const return args; } - - diff --git a/src/lib/CxxProject.h b/src/lib/CxxProject.h index deafe6b9..ac3a9779 100644 --- a/src/lib/CxxProject.h +++ b/src/lib/CxxProject.h @@ -16,7 +16,11 @@ protected: virtual const std::shared_ptr getProjectSettings() const; private: - CxxProject(std::shared_ptr projectSettings, StorageAccessProxy* storageAccessProxy); + CxxProject( + std::shared_ptr projectSettings, + StorageAccessProxy* storageAccessProxy, + DialogView* dialogView + ); CxxProject(const CxxProject&); virtual bool allowsRefresh(); diff --git a/src/lib/JavaProject.cpp b/src/lib/JavaProject.cpp index c210f6f1..f0103da0 100644 --- a/src/lib/JavaProject.cpp +++ b/src/lib/JavaProject.cpp @@ -18,8 +18,10 @@ const std::shared_ptr JavaProject::getProjectSettings() const return m_projectSettings; } -JavaProject::JavaProject(std::shared_ptr projectSettings, StorageAccessProxy* storageAccessProxy) - : Project(storageAccessProxy) +JavaProject::JavaProject( + std::shared_ptr projectSettings, StorageAccessProxy* storageAccessProxy, DialogView* dialogView +) + : Project(storageAccessProxy, dialogView) , m_projectSettings(projectSettings) { if (!JavaEnvironmentFactory::getInstance() && !isTrial()) @@ -69,7 +71,8 @@ std::shared_ptr JavaProject::createIndexerTask( storage, storageMutex, fileRegister, - arguments + arguments, + getDialogView() ); } diff --git a/src/lib/JavaProject.h b/src/lib/JavaProject.h index d41a1a3f..3eb68b13 100644 --- a/src/lib/JavaProject.h +++ b/src/lib/JavaProject.h @@ -16,7 +16,11 @@ protected: virtual const std::shared_ptr getProjectSettings() const; private: - JavaProject(std::shared_ptr projectSettings, StorageAccessProxy* storageAccessProxy); + JavaProject( + std::shared_ptr projectSettings, + StorageAccessProxy* storageAccessProxy, + DialogView* dialogView + ); JavaProject(const JavaProject&); virtual std::shared_ptr createIndexerTask( diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 07f37c51..81ee7836 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -1,12 +1,12 @@ #include "Project.h" +#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" #include "data/TaskCleanStorage.h" - #include "settings/ApplicationSettings.h" #include "settings/ProjectSettings.h" @@ -14,6 +14,7 @@ #include "utility/file/FileSystem.h" #include "utility/logging/logging.h" #include "utility/messaging/type/MessageFinishedParsing.h" +#include "utility/messaging/type/MessageStatus.h" #include "utility/scheduling/TaskGroupSequential.h" #include "utility/scheduling/TaskGroupParallel.h" #include "utility/text/TextAccess.h" @@ -26,7 +27,8 @@ #include "JavaProject.h" #include "isTrial.h" -std::shared_ptr Project::create(const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy) +std::shared_ptr Project::create( + const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView) { std::shared_ptr project; @@ -36,14 +38,14 @@ std::shared_ptr Project::create(const FilePath& projectSettingsFile, St case LANGUAGE_CPP: { project = std::shared_ptr(new CxxProject( - std::make_shared(projectSettingsFile), storageAccessProxy + std::make_shared(projectSettingsFile), storageAccessProxy, dialogView )); } break; case LANGUAGE_JAVA: { project = std::shared_ptr(new JavaProject( - std::make_shared(projectSettingsFile), storageAccessProxy + std::make_shared(projectSettingsFile), storageAccessProxy, dialogView )); } break; @@ -60,7 +62,7 @@ Project::~Project() { } -void Project::refresh() +bool Project::refresh(bool forceRefresh) { if (allowsRefresh()) { @@ -68,19 +70,14 @@ void Project::refresh() updateFileManager(m_fileManager); - buildIndex(); - - m_state = PROJECT_STATE_LOADED; + if (buildIndex(forceRefresh)) + { + m_state = PROJECT_STATE_LOADED; + return true; + } } -} -void Project::forceRefresh() -{ - if (allowsRefresh()) - { - clearStorage(); - } - refresh(); + return false; } FilePath Project::getProjectSettingsFilePath() const @@ -108,12 +105,18 @@ void Project::logStats() const m_storage->logStats(); } -Project::Project(StorageAccessProxy* storageAccessProxy) +Project::Project(StorageAccessProxy* storageAccessProxy, DialogView* dialogView) : m_storageAccessProxy(storageAccessProxy) + , m_dialogView(dialogView) , m_state(PROJECT_STATE_NOT_LOADED) { } +DialogView* Project::getDialogView() const +{ + return m_dialogView; +} + void Project::load() { const std::shared_ptr projectSettings = getProjectSettings(); @@ -151,7 +154,7 @@ void Project::load() switch (m_state) { case PROJECT_STATE_EMPTY: - buildIndex(); + buildIndex(false); m_state = PROJECT_STATE_LOADED; break; case PROJECT_STATE_OUTDATED: @@ -169,7 +172,8 @@ void Project::load() // dont break here. case PROJECT_STATE_LOADED: m_storage->finishParsing(); - MessageFinishedParsing(0, 0, 0, true).dispatch(); + MessageFinishedParsing().dispatch(); + MessageStatus("Finished Loading", false, false).dispatch(); break; case PROJECT_STATE_OUTVERSIONED: MessageStatus("Can't load project").dispatch(); @@ -193,7 +197,7 @@ void Project::load() if (reparse) { - forceRefresh(); + refresh(true); } } } @@ -214,17 +218,21 @@ void Project::clearStorage() } } -void Project::buildIndex() +bool Project::buildIndex(bool forceRefresh) { - m_storage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath().str())->getText()); + m_fileManager.fetchFilePaths( + forceRefresh ? std::vector() : m_storage->getInfoOnAllFiles() + ); - m_fileManager.fetchFilePaths(m_storage->getInfoOnAllFiles()); std::set addedFilePaths = m_fileManager.getAddedFilePaths(); std::set updatedFilePaths = m_fileManager.getUpdatedFilePaths(); std::set removedFilePaths = m_fileManager.getRemovedFilePaths(); - utility::append(updatedFilePaths, m_storage->getDependingFilePaths(updatedFilePaths)); - utility::append(updatedFilePaths, m_storage->getDependingFilePaths(removedFilePaths)); + if (!forceRefresh) + { + utility::append(updatedFilePaths, m_storage->getDependingFilePaths(updatedFilePaths)); + utility::append(updatedFilePaths, m_storage->getDependingFilePaths(removedFilePaths)); + } std::vector filesToClean; filesToClean.insert(filesToClean.end(), removedFilePaths.begin(), removedFilePaths.end()); @@ -237,12 +245,33 @@ void Project::buildIndex() if (!filesToClean.size() && !filesToParse.size()) { - MessageFinishedParsing(0, 0, 0, true).dispatch(); - return; + MessageStatus("Nothing to refresh, all files are up-to-date.").dispatch(); + return false; } + if (Application::getInstance()->hasGUI()) + { + bool doIndex = m_dialogView->startIndexingDialog(filesToClean.size(), filesToParse.size()); + + if (!doIndex) + { + return false; + } + } + + if (forceRefresh) + { + clearStorage(); + } + + m_storage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath().str())->getText()); + std::shared_ptr taskSequential = std::make_shared(); - taskSequential->addTask(std::make_shared(m_storage.get(), filesToClean)); + + if (filesToClean.size()) + { + taskSequential->addTask(std::make_shared(m_storage.get(), filesToClean, m_dialogView)); + } int indexerThreadCount = ApplicationSettings::getInstance()->getIndexerThreadCount(); @@ -251,7 +280,8 @@ void Project::buildIndex() std::shared_ptr taskParserWrapper = std::make_shared( m_storage.get(), - fileRegister + fileRegister, + m_dialogView ); taskSequential->addTask(taskParserWrapper); @@ -266,6 +296,8 @@ void Project::buildIndex() } Task::dispatch(taskSequential); + + return true; } bool Project::allowsRefresh() diff --git a/src/lib/Project.h b/src/lib/Project.h index 79404836..b2794965 100644 --- a/src/lib/Project.h +++ b/src/lib/Project.h @@ -10,6 +10,7 @@ #include "settings/ProjectSettings.h" // todo: use forward declaration here #include "utility/scheduling/Task.h" +class DialogView; class PersistentStorage; class StorageAccessProxy; class FileRegister; @@ -17,12 +18,12 @@ class FileRegister; class Project { public: - static std::shared_ptr create(const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy); + static std::shared_ptr create( + const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView); virtual ~Project(); - void refresh(); - void forceRefresh(); + bool refresh(bool forceRefresh); FilePath getProjectSettingsFilePath() const; LanguageType getLanguage() const; @@ -31,7 +32,8 @@ public: void logStats() const; protected: - Project(StorageAccessProxy* storageAccessProxy); + Project(StorageAccessProxy* storageAccessProxy, DialogView* dialogView); + DialogView* getDialogView() const; virtual std::shared_ptr getProjectSettings() = 0; virtual const std::shared_ptr getProjectSettings() const = 0; @@ -50,7 +52,7 @@ private: void load(); void clearStorage(); - void buildIndex(); + bool buildIndex(bool forceRefresh); virtual bool allowsRefresh(); virtual std::shared_ptr createIndexerTask( @@ -60,6 +62,7 @@ private: virtual void updateFileManager(FileManager& fileManager) = 0; StorageAccessProxy* const m_storageAccessProxy; + DialogView* m_dialogView; ProjectStateType m_state; FileManager m_fileManager; diff --git a/src/lib/component/ComponentManager.cpp b/src/lib/component/ComponentManager.cpp index 7d3fdb18..e85ce899 100644 --- a/src/lib/component/ComponentManager.cpp +++ b/src/lib/component/ComponentManager.cpp @@ -5,6 +5,7 @@ #include "component/controller/Controller.h" #include "component/view/CodeView.h" #include "component/view/CompositeView.h" +#include "component/view/DialogView.h" #include "component/view/GraphView.h" #include "component/view/RefreshView.h" #include "component/view/SearchView.h" @@ -50,6 +51,8 @@ void ComponentManager::setup(ViewLayout* viewLayout) std::shared_ptr featureComponent = m_componentFactory->createFeatureComponent(); m_components.push_back(featureComponent); + + m_dialogView = m_componentFactory->getViewFactory()->createDialogView(viewLayout); } void ComponentManager::clearComponents() @@ -83,6 +86,11 @@ void ComponentManager::refreshViews() } } +DialogView* ComponentManager::getDialogView() const +{ + return m_dialogView.get(); +} + ComponentManager::ComponentManager() { } diff --git a/src/lib/component/ComponentManager.h b/src/lib/component/ComponentManager.h index 13b07317..aae2a290 100644 --- a/src/lib/component/ComponentManager.h +++ b/src/lib/component/ComponentManager.h @@ -8,6 +8,7 @@ #include "component/ComponentFactory.h" class CompositeView; +class DialogView; class NetworkFactory; class StorageAccess; class View; @@ -26,6 +27,8 @@ public: void clearComponents(); void refreshViews(); + DialogView* getDialogView() const; + private: ComponentManager(); ComponentManager(const ComponentManager&); @@ -34,6 +37,8 @@ private: std::vector> m_compositeViews; std::vector> m_components; + + std::shared_ptr m_dialogView; }; #endif // COMPONENT_MANAGER_H diff --git a/src/lib/component/controller/StatusBarController.cpp b/src/lib/component/controller/StatusBarController.cpp index 5a505b4c..364872bd 100644 --- a/src/lib/component/controller/StatusBarController.cpp +++ b/src/lib/component/controller/StatusBarController.cpp @@ -32,15 +32,6 @@ void StatusBarController::handleMessage(MessageFinishedParsing* message) { ErrorCountInfo errorCount = m_storageAccess->getErrorCount(); getView()->setErrorCount(errorCount); - - std::string status = message->getStatusStr(); - status += "; " + std::to_string(errorCount.total) + " error" + (errorCount.total != 1 ? "s" : ""); - if (errorCount.fatal > 0) - { - status += " (" + std::to_string(errorCount.fatal) + " fatal)"; - } - - MessageStatus(status, false).dispatch(); } void StatusBarController::handleMessage(MessageRefresh* message) diff --git a/src/lib/component/view/DialogView.cpp b/src/lib/component/view/DialogView.cpp new file mode 100644 index 00000000..c8e81f2e --- /dev/null +++ b/src/lib/component/view/DialogView.cpp @@ -0,0 +1,40 @@ +#include "component/view/DialogView.h" + +DialogView::DialogView() +{ +} + +DialogView::~DialogView() +{ +} + +void DialogView::showProgressDialog(const std::string& title, const std::string& message) +{ +} + +void DialogView::hideProgressDialog() +{ +} + +bool DialogView::startIndexingDialog(size_t cleanFileCount, size_t indexFileCount) +{ + return false; +} + +void DialogView::updateIndexingDialog(size_t fileCount, size_t totalFileCount, std::string sourcePath) +{ +} + +void DialogView::finishedIndexingDialog(size_t fileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo) +{ +} + +int DialogView::confirm(const std::string& message) +{ + return confirm(message, std::vector()); +} + +int DialogView::confirm(const std::string& message, const std::vector& options) +{ + return -1; +} diff --git a/src/lib/component/view/DialogView.h b/src/lib/component/view/DialogView.h new file mode 100644 index 00000000..df84774b --- /dev/null +++ b/src/lib/component/view/DialogView.h @@ -0,0 +1,26 @@ +#ifndef DIALOG_VIEW_H +#define DIALOG_VIEW_H + +#include +#include + +#include "data/ErrorCountInfo.h" + +class DialogView +{ +public: + DialogView(); + virtual ~DialogView(); + + virtual void showProgressDialog(const std::string& title, const std::string& message); + virtual void hideProgressDialog(); + + virtual bool startIndexingDialog(size_t cleanFileCount, size_t indexFileCount); + virtual void updateIndexingDialog(size_t fileCount, size_t totalFileCount, std::string sourcePath); + virtual void finishedIndexingDialog(size_t fileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo); + + int confirm(const std::string& message); + virtual int confirm(const std::string& message, const std::vector& options); +}; + +#endif // DIALOG_VIEW_H diff --git a/src/lib/component/view/MainView.cpp b/src/lib/component/view/MainView.cpp index b5c8b400..046c0401 100644 --- a/src/lib/component/view/MainView.cpp +++ b/src/lib/component/view/MainView.cpp @@ -7,8 +7,3 @@ MainView::MainView() MainView::~MainView() { } - -int MainView::confirm(const std::string& message) -{ - return confirm(message, std::vector()); -} diff --git a/src/lib/component/view/MainView.h b/src/lib/component/view/MainView.h index f8a7c55a..776b9e14 100644 --- a/src/lib/component/view/MainView.h +++ b/src/lib/component/view/MainView.h @@ -17,9 +17,6 @@ public: virtual void setTitle(const std::string& title) = 0; virtual void activateWindow() = 0; virtual void updateRecentProjectMenu() = 0; - - virtual int confirm(const std::string& message); - virtual int confirm(const std::string& message, const std::vector& options) = 0; }; #endif // MAIN_VIEW_H diff --git a/src/lib/component/view/ViewFactory.h b/src/lib/component/view/ViewFactory.h index 803a85ef..ff4094b0 100644 --- a/src/lib/component/view/ViewFactory.h +++ b/src/lib/component/view/ViewFactory.h @@ -6,6 +6,7 @@ #include "component/view/CompositeView.h" class CodeView; +class DialogView; class GraphView; class MainView; class RefreshView; @@ -30,6 +31,8 @@ public: virtual std::shared_ptr createSearchView(ViewLayout* viewLayout) const = 0; virtual std::shared_ptr createStatusBarView(ViewLayout* viewLayout) const = 0; virtual std::shared_ptr createUndoRedoView(ViewLayout* viewLayout) const = 0; + + virtual std::shared_ptr createDialogView(ViewLayout* viewLayout) const = 0; }; #endif // VIEW_FACTORY_H diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index 4581721e..028618a7 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -366,6 +366,8 @@ void PersistentStorage::logStats() const void PersistentStorage::startParsing() { + clearCaches(); + MessageClearErrorCount().dispatch(); m_sqliteStorage.setVersion(); diff --git a/src/lib/data/TaskCleanStorage.cpp b/src/lib/data/TaskCleanStorage.cpp index c520f97f..ce0c5289 100644 --- a/src/lib/data/TaskCleanStorage.cpp +++ b/src/lib/data/TaskCleanStorage.cpp @@ -1,58 +1,44 @@ #include "data/TaskCleanStorage.h" +#include "component/view/DialogView.h" #include "data/PersistentStorage.h" -#include "utility/messaging/type/MessageStatus.h" -#include "utility/utility.h" -TaskCleanStorage::TaskCleanStorage(PersistentStorage* storage, const std::vector& filePaths) +TaskCleanStorage::TaskCleanStorage( + PersistentStorage* storage, const std::vector& filePaths, DialogView* dialogView +) : m_storage(storage) , m_filePaths(filePaths) - , m_fileCount(filePaths.size()) + , m_dialogView(dialogView) { } void TaskCleanStorage::enter() { - m_start = utility::durationStart(); + m_dialogView->showProgressDialog("Clearing Files", std::to_string(m_filePaths.size()) + " Files"); } Task::TaskState TaskCleanStorage::update() { - if (m_filePaths.size()) - { - std::stringstream ss; - ss << "clearing " << m_filePaths.size() << " files (ESC to quit)"; - MessageStatus(ss.str(), false, true).dispatch(); + m_storage->clearFileElements(m_filePaths); - m_storage->clearFileElements(m_filePaths); - - m_filePaths.clear(); - - return Task::STATE_RUNNING; - } - - if (m_fileCount) - { - MessageStatus("Clearing caches (ESC to quit)", false, true).dispatch(); - m_storage->clearCaches(); - } + m_filePaths.clear(); return Task::STATE_FINISHED; } void TaskCleanStorage::exit() { - std::stringstream ss; - ss << "clearing files done, "; - ss << std::setprecision(2) << std::fixed << utility::duration(m_start) << " seconds"; - MessageStatus(ss.str()).dispatch(); + m_dialogView->hideProgressDialog(); } void TaskCleanStorage::interrupt() { - MessageStatus("clearing files interrupted", false, true).dispatch(); } void TaskCleanStorage::revert() { } + +void TaskCleanStorage::abort() +{ +} diff --git a/src/lib/data/TaskCleanStorage.h b/src/lib/data/TaskCleanStorage.h index 1066a908..712f713d 100644 --- a/src/lib/data/TaskCleanStorage.h +++ b/src/lib/data/TaskCleanStorage.h @@ -5,8 +5,8 @@ #include "utility/file/FilePath.h" #include "utility/scheduling/Task.h" -#include "utility/TimePoint.h" +class DialogView; class PersistentStorage; class TaskCleanStorage @@ -15,7 +15,8 @@ class TaskCleanStorage public: TaskCleanStorage( PersistentStorage* storage, - const std::vector& filePaths + const std::vector& filePaths, + DialogView* dialogView ); virtual void enter(); @@ -24,13 +25,12 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: PersistentStorage* m_storage; std::vector m_filePaths; - const size_t m_fileCount; - - TimePoint m_start; + DialogView* m_dialogView; }; #endif // TASK_PARSE_CXX_H diff --git a/src/lib/data/parser/cxx/TaskParseCxx.h b/src/lib/data/parser/cxx/TaskParseCxx.h index 15beb767..72596082 100644 --- a/src/lib/data/parser/cxx/TaskParseCxx.h +++ b/src/lib/data/parser/cxx/TaskParseCxx.h @@ -10,9 +10,10 @@ #include "utility/scheduling/Task.h" #include "utility/TimePoint.h" -class PersistentStorage; -class FileRegister; class CxxParser; +class DialogView; +class FileRegister; +class PersistentStorage; namespace clang { @@ -32,7 +33,8 @@ public: PersistentStorage* storage, std::shared_ptr storageMutex, std::shared_ptr fileRegister, - const Parser::Arguments& arguments + const Parser::Arguments& arguments, + DialogView* dialogView ); virtual void enter(); @@ -41,13 +43,17 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: PersistentStorage* m_storage; std::shared_ptr m_storageMutex; + + const Parser::Arguments m_arguments; + DialogView* m_dialogView; + std::shared_ptr m_parser; std::shared_ptr m_parserClient; - const Parser::Arguments m_arguments; bool m_isCDB; std::shared_ptr m_cdb; diff --git a/src/lib/data/parser/cxx/TaskParseWrapper.h b/src/lib/data/parser/cxx/TaskParseWrapper.h index e1b4eb4a..17564b5a 100644 --- a/src/lib/data/parser/cxx/TaskParseWrapper.h +++ b/src/lib/data/parser/cxx/TaskParseWrapper.h @@ -8,8 +8,9 @@ #include "utility/scheduling/TaskDecorator.h" #include "utility/TimePoint.h" -class PersistentStorage; +class DialogView; class FileRegister; +class PersistentStorage; class TaskParseWrapper : public TaskDecorator @@ -17,7 +18,8 @@ class TaskParseWrapper public: TaskParseWrapper( PersistentStorage* storage, - std::shared_ptr fileRegister + std::shared_ptr fileRegister, + DialogView* dialogView ); virtual ~TaskParseWrapper(); @@ -27,10 +29,13 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: PersistentStorage* m_storage; std::shared_ptr m_fileRegister; + DialogView* m_dialogView; + TimePoint m_start; }; diff --git a/src/lib/data/parser/java/TaskParseJava.h b/src/lib/data/parser/java/TaskParseJava.h index 1669a8a4..6bc99655 100644 --- a/src/lib/data/parser/java/TaskParseJava.h +++ b/src/lib/data/parser/java/TaskParseJava.h @@ -6,6 +6,7 @@ #include "data/parser/Parser.h" #include "utility/scheduling/Task.h" +class DialogView; class FileRegister; class PersistentStorage; @@ -17,7 +18,8 @@ public: PersistentStorage* storage, std::shared_ptr storageMutex, std::shared_ptr fileRegister, - const Parser::Arguments& arguments + const Parser::Arguments& arguments, + DialogView* dialogView ); virtual void enter(); @@ -26,12 +28,14 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: PersistentStorage* m_storage; std::shared_ptr m_storageMutex; std::shared_ptr m_fileRegister; Parser::Arguments m_arguments; + DialogView* m_dialogView; }; #endif // TASK_PARSE_JAVA_H diff --git a/src/lib/utility/TimePoint.cpp b/src/lib/utility/TimePoint.cpp index e7554b9a..37456ee3 100644 --- a/src/lib/utility/TimePoint.cpp +++ b/src/lib/utility/TimePoint.cpp @@ -1,5 +1,10 @@ #include "TimePoint.h" +TimePoint TimePoint::now() +{ + return TimePoint(boost::posix_time::microsec_clock::local_time()); +} + TimePoint::TimePoint() : m_time(boost::posix_time::not_a_date_time) { @@ -37,4 +42,9 @@ std::string TimePoint::toString() const stream.imbue(std::locale(std::locale::classic(), facet)); stream << m_time; return stream.str(); -} \ No newline at end of file +} + +size_t TimePoint::deltaMS(const TimePoint& other) const +{ + return (m_time - other.m_time).total_milliseconds(); +} diff --git a/src/lib/utility/TimePoint.h b/src/lib/utility/TimePoint.h index 12edef2b..09f31da8 100644 --- a/src/lib/utility/TimePoint.h +++ b/src/lib/utility/TimePoint.h @@ -6,6 +6,8 @@ class TimePoint { public: + static TimePoint now(); + TimePoint(); TimePoint(boost::posix_time::ptime t); //TimePoint(time_t t); @@ -22,7 +24,9 @@ public: inline bool operator<=(const TimePoint& rhs){ return m_time <= rhs.m_time; } inline bool operator>=(const TimePoint& rhs){ return m_time >= rhs.m_time; } - inline float operator-(const TimePoint& rhs){ return (m_time - rhs.m_time).total_milliseconds() / 1000.0f; } + inline float operator-(const TimePoint& rhs){ return deltaMS(rhs) / 1000.0f; } + + size_t deltaMS(const TimePoint& other) const; private: boost::posix_time::ptime m_time; diff --git a/src/lib/utility/messaging/type/MessageFinishedParsing.h b/src/lib/utility/messaging/type/MessageFinishedParsing.h index 0612b34c..bb7e46e0 100644 --- a/src/lib/utility/messaging/type/MessageFinishedParsing.h +++ b/src/lib/utility/messaging/type/MessageFinishedParsing.h @@ -1,22 +1,13 @@ #ifndef MESSAGE_FINISHED_PARSING_H #define MESSAGE_FINISHED_PARSING_H -#include -#include - -#include "data/ErrorCountInfo.h" #include "utility/messaging/Message.h" -#include "utility/messaging/type/MessageStatus.h" class MessageFinishedParsing : public Message { public: - MessageFinishedParsing(size_t fileCount, size_t totalFileCount, float parseTime, bool loadedOnly = false) - : fileCount(fileCount) - , totalFileCount(totalFileCount) - , parseTime(parseTime) - , loadedOnly(loadedOnly) + MessageFinishedParsing() { } @@ -24,55 +15,6 @@ public: { return "MessageFinishedParsing"; } - - std::string getStatusStr() const - { - if (loadedOnly) - { - return "Finished loading"; - } - - std::stringstream ss; - ss << "Finished indexing: "; - ss << fileCount << "/" << totalFileCount << " files; "; - - float secondsLeft = parseTime; - int hours = int(secondsLeft / 3600); - secondsLeft -= hours * 3600; - int minutes = int(secondsLeft / 60); - secondsLeft -= minutes * 60; - int seconds = int(secondsLeft); - secondsLeft -= seconds; - int milliSeconds = secondsLeft * 1000; - - if (hours > 9) - { - ss << hours; - } - else - { - ss << std::setw(2) << std::setfill('0') << hours; - } - ss << ":" << std::setw(2) << std::setfill('0') << minutes; - ss << ":" << std::setw(2) << std::setfill('0') << seconds; - - if (!hours && !minutes) - { - ss << ":" << std::setw(3) << std::setfill('0') << milliSeconds; - } - - return ss.str(); - } - - virtual void print(std::ostream& os) const - { - os << getStatusStr(); - } - - size_t fileCount; - size_t totalFileCount; - float parseTime; - bool loadedOnly; }; #endif // MESSAGE_FINISHED_PARSING_H diff --git a/src/lib/utility/scheduling/Task.cpp b/src/lib/utility/scheduling/Task.cpp index afe94960..762ad091 100644 --- a/src/lib/utility/scheduling/Task.cpp +++ b/src/lib/utility/scheduling/Task.cpp @@ -62,6 +62,8 @@ Task::TaskState Task::interruptTask() switch (m_state) { case STATE_NEW: + abort(); + break; case STATE_CANCELED: break; case STATE_RUNNING: diff --git a/src/lib/utility/scheduling/Task.h b/src/lib/utility/scheduling/Task.h index d4a3b221..23d62ac7 100644 --- a/src/lib/utility/scheduling/Task.h +++ b/src/lib/utility/scheduling/Task.h @@ -33,6 +33,7 @@ public: virtual void interrupt() = 0; virtual void revert() = 0; + virtual void abort() = 0; protected: void setState(TaskState state); diff --git a/src/lib/utility/scheduling/TaskGroupParallel.cpp b/src/lib/utility/scheduling/TaskGroupParallel.cpp index fec10263..8fce2e81 100644 --- a/src/lib/utility/scheduling/TaskGroupParallel.cpp +++ b/src/lib/utility/scheduling/TaskGroupParallel.cpp @@ -62,6 +62,11 @@ void TaskGroupParallel::revert() m_interrupt = true; } +void TaskGroupParallel::abort() +{ + m_interrupt = true; +} + void TaskGroupParallel::processTaskThreaded(std::shared_ptr task) { diff --git a/src/lib/utility/scheduling/TaskGroupParallel.h b/src/lib/utility/scheduling/TaskGroupParallel.h index 5b25c943..371af8e8 100644 --- a/src/lib/utility/scheduling/TaskGroupParallel.h +++ b/src/lib/utility/scheduling/TaskGroupParallel.h @@ -19,6 +19,7 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: void processTaskThreaded(std::shared_ptr task); diff --git a/src/lib/utility/scheduling/TaskGroupSequential.cpp b/src/lib/utility/scheduling/TaskGroupSequential.cpp index 42a75d8a..67c140c6 100644 --- a/src/lib/utility/scheduling/TaskGroupSequential.cpp +++ b/src/lib/utility/scheduling/TaskGroupSequential.cpp @@ -43,12 +43,9 @@ void TaskGroupSequential::exit() void TaskGroupSequential::interrupt() { - if (m_taskIndex >= 0 && size_t(m_taskIndex) < m_tasks.size()) + for (size_t i = 0; i < m_tasks.size(); i++) { - for (int i = m_taskIndex; i >= 0; i--) - { - m_tasks[i]->interruptTask(); - } + m_tasks[i]->interruptTask(); } } @@ -59,3 +56,8 @@ void TaskGroupSequential::revert() m_tasks[i]->interruptTask(); } } + +void TaskGroupSequential::abort() +{ + interrupt(); +} diff --git a/src/lib/utility/scheduling/TaskGroupSequential.h b/src/lib/utility/scheduling/TaskGroupSequential.h index f71461ed..43d05fd1 100644 --- a/src/lib/utility/scheduling/TaskGroupSequential.h +++ b/src/lib/utility/scheduling/TaskGroupSequential.h @@ -16,6 +16,7 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: int m_taskIndex; diff --git a/src/lib/utility/scheduling/TaskLambda.cpp b/src/lib/utility/scheduling/TaskLambda.cpp index 7b448f98..7639bb1a 100644 --- a/src/lib/utility/scheduling/TaskLambda.cpp +++ b/src/lib/utility/scheduling/TaskLambda.cpp @@ -30,3 +30,7 @@ void TaskLambda::interrupt() void TaskLambda::revert() { } + +void TaskLambda::abort() +{ +} diff --git a/src/lib/utility/scheduling/TaskLambda.h b/src/lib/utility/scheduling/TaskLambda.h index ffe7bbe0..f77fe64c 100644 --- a/src/lib/utility/scheduling/TaskLambda.h +++ b/src/lib/utility/scheduling/TaskLambda.h @@ -18,6 +18,7 @@ public: virtual void interrupt(); virtual void revert(); + virtual void abort(); private: std::function m_func; diff --git a/src/lib/utility/utility.cpp b/src/lib/utility/utility.cpp index 59ae3123..ee2eed31 100644 --- a/src/lib/utility/utility.cpp +++ b/src/lib/utility/utility.cpp @@ -1,9 +1,13 @@ #include "utility/utility.h" + +#include +#include + #include "boost/date_time/time_clock.hpp" TimePoint utility::durationStart() { - return TimePoint(boost::posix_time::microsec_clock::local_time()); + return TimePoint::now(); } float utility::duration(const TimePoint& start) @@ -33,6 +37,37 @@ std::string utility::timeToString(const boost::posix_time::ptime time) return TimePoint(time).toString(); } +std::string utility::timeToString(float secondsTotal) +{ + std::stringstream ss; + + int hours = int(secondsTotal / 3600); + secondsTotal -= hours * 3600; + int minutes = int(secondsTotal / 60); + secondsTotal -= minutes * 60; + int seconds = int(secondsTotal); + secondsTotal -= seconds; + int milliSeconds = secondsTotal * 1000; + + if (hours > 9) + { + ss << hours; + } + else + { + ss << std::setw(2) << std::setfill('0') << hours; + } + ss << ":" << std::setw(2) << std::setfill('0') << minutes; + ss << ":" << std::setw(2) << std::setfill('0') << seconds; + + if (!hours && !minutes) + { + ss << ":" << std::setw(3) << std::setfill('0') << milliSeconds; + } + + return ss.str(); +} + bool utility::intersectionPoint(Vec2f a1, Vec2f b1, Vec2f a2, Vec2f b2, Vec2f* i) { Vec2f p = a1; diff --git a/src/lib/utility/utility.h b/src/lib/utility/utility.h index 0e24966f..af4783b3 100644 --- a/src/lib/utility/utility.h +++ b/src/lib/utility/utility.h @@ -21,6 +21,7 @@ namespace utility std::string timeToString(const time_t time); std::string timeToString(const boost::posix_time::ptime time); + std::string timeToString(float seconds); template std::vector concat(const std::vector& a, const std::vector& b); diff --git a/src/lib_gui/CMakeLists.txt b/src/lib_gui/CMakeLists.txt index a1be57a2..d127a969 100644 --- a/src/lib_gui/CMakeLists.txt +++ b/src/lib_gui/CMakeLists.txt @@ -24,13 +24,14 @@ add_files( qt/element/QtLineEdit.h qt/element/QtLocationPicker.cpp qt/element/QtLocationPicker.h + qt/element/QtProgressBar.cpp + qt/element/QtProgressBar.h qt/element/QtRefreshBar.cpp qt/element/QtRefreshBar.h qt/element/QtSearchBar.cpp qt/element/QtSearchBar.h qt/element/QtSmartSearchBox.cpp qt/element/QtSmartSearchBox.h - qt/element/QtStatusBar.cpp qt/element/QtStatusBar.h qt/element/QtUndoRedo.cpp @@ -90,6 +91,8 @@ add_files( qt/view/QtCodeView.h qt/view/QtCompositeView.cpp qt/view/QtCompositeView.h + qt/view/QtDialogView.cpp + qt/view/QtDialogView.h qt/view/QtGraphView.cpp qt/view/QtGraphView.h qt/view/QtGraphViewStyleImpl.cpp @@ -140,6 +143,8 @@ add_files( qt/window/QtAbout.h qt/window/QtAboutLicense.cpp qt/window/QtAboutLicense.h + qt/window/QtIndexingDialog.cpp + qt/window/QtIndexingDialog.h qt/window/QtLicense.cpp qt/window/QtLicense.h qt/window/QtMainWindow.cpp diff --git a/src/lib_gui/qt/element/QtProgressBar.cpp b/src/lib_gui/qt/element/QtProgressBar.cpp new file mode 100644 index 00000000..e004104a --- /dev/null +++ b/src/lib_gui/qt/element/QtProgressBar.cpp @@ -0,0 +1,83 @@ +#include "qt/element/QtProgressBar.h" + +#include +#include +#include +#include + +#include "utility/ResourcePaths.h" + +QtProgressBar::QtProgressBar(QWidget* parent) + : QWidget(parent) + , m_percent(0) + , m_count(0) + , m_pixmap((ResourcePaths::getGuiPath() + "indexing_dialog/progress_bar_element.png").c_str()) +{ + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(animate())); + + m_pixmap.scaleToHeight(20); +} + +void QtProgressBar::showProgress(size_t percent) +{ + m_percent = percent; + + stop(); + show(); + + update(); +} + +void QtProgressBar::showUnknownProgressAnimated() +{ + start(); + show(); +} + +void QtProgressBar::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + + if (m_count) + { + const QPixmap& pixmap = m_pixmap.pixmap(); + + for (int x = -36 + (m_count % 36); x < geometry().width(); x += 18) + { + painter.drawPixmap(QPointF(x, -5), pixmap); + } + } + else + { + painter.fillRect(0, 2, geometry().width() * m_percent / 100, 6, "white"); + } +} + +void QtProgressBar::start() +{ + m_timePoint = TimePoint::now(); + m_timer->start(25); +} + +void QtProgressBar::stop() +{ + m_timer->stop(); + m_count = 0; +} + +void QtProgressBar::animate() +{ + TimePoint t = TimePoint::now(); + size_t dt = t.deltaMS(m_timePoint); + + if (dt < 5) + { + return; + } + + m_timePoint = t; + m_count++; + + update(); +} diff --git a/src/lib_gui/qt/element/QtProgressBar.h b/src/lib_gui/qt/element/QtProgressBar.h new file mode 100644 index 00000000..f374e2ef --- /dev/null +++ b/src/lib_gui/qt/element/QtProgressBar.h @@ -0,0 +1,42 @@ +#ifndef QT_PROGRESS_BAR_H +#define QT_PROGRESS_BAR_H + +#include + +#include "qt/utility/QtDeviceScaledPixmap.h" +#include "utility/TimePoint.h" + +class QTimer; + +class QtProgressBar + : public QWidget +{ + Q_OBJECT + +public: + QtProgressBar(QWidget* parent = nullptr); + + void showProgress(size_t percent); + + void showUnknownProgressAnimated(); + +protected: + void paintEvent(QPaintEvent* event); + +private slots: + void start(); + void stop(); + + void animate(); + +private: + size_t m_percent; + + size_t m_count; + QTimer* m_timer; + TimePoint m_timePoint; + + QtDeviceScaledPixmap m_pixmap; +}; + +#endif // QT_PROGRESS_BAR_H diff --git a/src/lib_gui/qt/element/QtStatusBar.cpp b/src/lib_gui/qt/element/QtStatusBar.cpp index 47e95ca2..a4845168 100644 --- a/src/lib_gui/qt/element/QtStatusBar.cpp +++ b/src/lib_gui/qt/element/QtStatusBar.cpp @@ -9,6 +9,8 @@ QtStatusBar::QtStatusBar() : m_text(this) { + addWidget(new QWidget()); // add some space + QMovie* movie = new QMovie((ResourcePaths::getGuiPath() + "statusbar_view/loader.gif").c_str()); // if movie doesn't loop forever, force it to. if (movie->loopCount() != -1) diff --git a/src/lib_gui/qt/utility/QtThreadedFunctor.h b/src/lib_gui/qt/utility/QtThreadedFunctor.h index 28e743cd..f6d47c98 100644 --- a/src/lib_gui/qt/utility/QtThreadedFunctor.h +++ b/src/lib_gui/qt/utility/QtThreadedFunctor.h @@ -1,7 +1,9 @@ #ifndef QT_THREADED_FUCTOR_H #define QT_THREADED_FUCTOR_H +#include #include +#include #include #include @@ -119,4 +121,17 @@ private: std::function m_callback; }; + +class QtThreadedLambdaFunctor +{ +public: + void operator()(std::function callback) + { + m_helper(callback); + } + +private: + QtThreadedFunctorHelper m_helper; +}; + #endif // QT_THREADED_FUCTOR_H diff --git a/src/lib_gui/qt/view/QtDialogView.cpp b/src/lib_gui/qt/view/QtDialogView.cpp new file mode 100644 index 00000000..4bd362ec --- /dev/null +++ b/src/lib_gui/qt/view/QtDialogView.cpp @@ -0,0 +1,255 @@ +#include "qt/view/QtDialogView.h" + +#include +#include +#include + +#include + +#include "qt/window/QtIndexingDialog.h" +#include "qt/window/QtMainWindow.h" +#include "utility/messaging/type/MessageStatus.h" +#include "utility/utility.h" + +QtDialogView::QtDialogView(QtMainWindow* mainWindow) + : m_mainWindow(mainWindow) + , m_windowStack(this) +{ +} + +QtDialogView::~QtDialogView() +{ +} + +void QtDialogView::showProgressDialog(const std::string& title, const std::string& message) +{ + MessageStatus(title + ": " + message, false, true).dispatch(); + + m_onQtThread( + [=]() + { + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (!window || window->getType() != QtIndexingDialog::DIALOG_PROGRESS) + { + m_windowStack.clearWindows(); + + window = createWindow(); + window->setupProgress(); + } + + window->updateTitle(title.c_str()); + window->updateMessage(message.c_str()); + + setUIBlocked(true); + } + ); +} + +void QtDialogView::hideProgressDialog() +{ + MessageStatus("", false, false).dispatch(); + + m_onQtThread( + [=]() + { + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (window && window->getType() == QtIndexingDialog::DIALOG_PROGRESS) + { + m_windowStack.popWindow(); + } + + setUIBlocked(false); + } + ); +} + +bool QtDialogView::startIndexingDialog(size_t cleanFileCount, size_t indexFileCount) +{ + bool result = false; + bool done = false; + + m_onQtThread( + [=, &result, &done]() + { + QtIndexingDialog* window = createWindow(); + window->setupStart(cleanFileCount, indexFileCount, + [&](bool start) + { + result = start; + done = true; + + setUIBlocked(false); + } + ); + + setUIBlocked(true); + } + ); + + while (!done) + { + const int SLEEP_TIME_MS = 25; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); + } + + return result; +} + +void QtDialogView::updateIndexingDialog(size_t fileCount, size_t totalFileCount, std::string sourcePath) +{ + std::stringstream ss; + ss << "Indexing files: ["; + ss << fileCount << "/"; + ss << totalFileCount << "] "; + ss << sourcePath; + MessageStatus(ss.str(), false, true).dispatch(); + + m_onQtThread( + [=]() + { + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (!window) + { + m_windowStack.clearWindows(); + + window = createWindow(); + window->setupIndexing(); + } + + if (window && window->getType() == QtIndexingDialog::DIALOG_INDEXING) + { + window->updateIndexingProgress(fileCount, totalFileCount, sourcePath); + setUIBlocked(true); + } + } + ); +} + +void QtDialogView::finishedIndexingDialog(size_t fileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo) +{ + std::stringstream ss; + ss << "Finished indexing: "; + ss << fileCount << "/" << totalFileCount << " files; "; + ss << utility::timeToString(time); + ss << "; " << errorInfo.total << " error" << (errorInfo.total != 1 ? "s" : ""); + if (errorInfo.fatal > 0) + { + ss << " (" << errorInfo.fatal << " fatal)"; + } + MessageStatus(ss.str(), false, false).dispatch(); + + m_onQtThread( + [=]() + { + m_windowStack.clearWindows(); + + QtIndexingDialog* window = createWindow(); + window->setupReport(fileCount, totalFileCount, time); + window->updateErrorCount(errorInfo.total, errorInfo.fatal); + + setUIBlocked(false); + } + ); +} + +int QtDialogView::confirm(const std::string& message, const std::vector& options) +{ + int result = -1; + bool done = false; + + m_onQtThread( + [=, &result, &done]() + { + QMessageBox msgBox; + msgBox.setText(message.c_str()); + + for (const std::string& option : options) + { + msgBox.addButton(option.c_str(), QMessageBox::AcceptRole); + } + + msgBox.exec(); + + for (int i = 0; i < msgBox.buttons().size(); i++) + { + if (msgBox.clickedButton() == msgBox.buttons().at(i)) + { + result = i; + break; + } + } + + done = true; + } + ); + + while (!done) + { + const int SLEEP_TIME_MS = 25; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); + } + + return result; +} + +void QtDialogView::handleMessage(MessageInterruptTasks* message) +{ + m_onQtThread2( + [=]() + { + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (window && window->getType() == QtIndexingDialog::DIALOG_INDEXING) + { + showProgressDialog("Interrupting Indexing", "Waiting for indexer threads to finish"); + } + } + ); +} + +void QtDialogView::handleMessage(MessageShowErrors* message) +{ + ErrorCountInfo errorInfo = message->errorCount; + + m_onQtThread2( + [=]() + { + updateErrorCount(errorInfo.total, errorInfo.fatal); + } + ); +} + +void QtDialogView::updateErrorCount(size_t errorCount, size_t fatalCount) +{ + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (window) + { + window->updateErrorCount(errorCount, fatalCount); + } +} + +template + T* QtDialogView::createWindow() +{ + T* window = new T(m_mainWindow); + + connect(window, SIGNAL(canceled()), &m_windowStack, SLOT(popWindow())); + connect(window, SIGNAL(finished()), &m_windowStack, SLOT(clearWindows())); + + m_windowStack.pushWindow(window); + + return window; +} + +void QtDialogView::setUIBlocked(bool blocked) +{ + m_mainWindow->setEnabled(!blocked); + + if (blocked) + { + QWidget* window = m_windowStack.getTopWindow(); + if (window) + { + window->setEnabled(true); + } + } +} diff --git a/src/lib_gui/qt/view/QtDialogView.h b/src/lib_gui/qt/view/QtDialogView.h new file mode 100644 index 00000000..6b5e530e --- /dev/null +++ b/src/lib_gui/qt/view/QtDialogView.h @@ -0,0 +1,55 @@ +#ifndef QT_DIALOG_VIEW_H +#define QT_DIALOG_VIEW_H + +#include "component/view/DialogView.h" + +#include "qt/utility/QtThreadedFunctor.h" +#include "qt/window/QtWindowStack.h" + +#include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/MessageInterruptTasks.h" +#include "utility/messaging/type/MessageShowErrors.h" + +class QtMainWindow; + +class QtDialogView + : public QObject + , public DialogView + , public MessageListener + , public MessageListener +{ + Q_OBJECT + +public: + QtDialogView(QtMainWindow* mainWindow); + virtual ~QtDialogView(); + + void showProgressDialog(const std::string& title, const std::string& message) override; + void hideProgressDialog() override; + + bool startIndexingDialog(size_t cleanFileCount, size_t indexFileCount) override; + void updateIndexingDialog(size_t fileCount, size_t totalFileCount, std::string sourcePath) override; + void finishedIndexingDialog(size_t fileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo) override; + + int confirm(const std::string& message, const std::vector& options) override; + +private: + void handleMessage(MessageInterruptTasks* message) override; + void handleMessage(MessageShowErrors* message) override; + + void updateErrorCount(size_t errorCount, size_t fatalCount); + + template + T* createWindow(); + + void setUIBlocked(bool blocked); + + QtMainWindow* m_mainWindow; + + QtWindowStack m_windowStack; + + QtThreadedLambdaFunctor m_onQtThread; + QtThreadedLambdaFunctor m_onQtThread2; +}; + +#endif // QT_DIALOG_VIEW_H diff --git a/src/lib_gui/qt/view/QtMainView.cpp b/src/lib_gui/qt/view/QtMainView.cpp index 39c24088..fce66c86 100644 --- a/src/lib_gui/qt/view/QtMainView.cpp +++ b/src/lib_gui/qt/view/QtMainView.cpp @@ -1,12 +1,5 @@ #include "qt/view/QtMainView.h" -#include -#include - -#include - -#include "utility/logging/logging.h" - #include "qt/window/QtMainWindow.h" QtMainView::QtMainView() @@ -18,7 +11,6 @@ QtMainView::QtMainView() , m_activateWindowFunctor(std::bind(&QtMainView::doActivateWindow, this)) , m_updateRecentProjectMenuFunctor(std::bind(&QtMainView::doUpdateRecentProjectMenu, this)) , m_forceLicenseScreenFunctor(std::bind(&QtMainView::doForceLicenseScreen, this, std::placeholders::_1)) - , m_confirmFunctor(std::bind(&QtMainView::doConfirm, this, std::placeholders::_1, std::placeholders::_2)) { m_window = std::make_shared(); m_window->show(); @@ -28,6 +20,11 @@ QtMainView::~QtMainView() { } +QtMainWindow* QtMainView::getMainWindow() const +{ + return m_window.get(); +} + void QtMainView::addView(View* view) { m_views.push_back(view); @@ -96,30 +93,6 @@ void QtMainView::updateRecentProjectMenu() m_updateRecentProjectMenuFunctor(); } -int QtMainView::confirm(const std::string& message, const std::vector& options) -{ - m_confirmDone = false; - - m_confirmFunctor(message, options); - - while (true) - { - { - std::lock_guard lock(m_confirmMutex); - - if (m_confirmDone) - { - break; - } - } - - const int SLEEP_TIME_MS = 25; - std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); - } - - return m_confirmResult; -} - void QtMainView::handleMessage(MessageForceEnterLicense* message) { m_forceLicenseScreenFunctor(message->licenseExpired); @@ -185,30 +158,3 @@ void QtMainView::doForceLicenseScreen(bool expired) { m_window->forceEnterLicense(expired); } - -void QtMainView::doConfirm(const std::string& message, const std::vector& options) -{ - QMessageBox msgBox; - msgBox.setText(message.c_str()); - - for (const std::string& option : options) - { - msgBox.addButton(option.c_str(), QMessageBox::AcceptRole); - } - - msgBox.exec(); - - m_confirmResult = -1; - - for (int i = 0; i < msgBox.buttons().size(); i++) - { - if (msgBox.clickedButton() == msgBox.buttons().at(i)) - { - m_confirmResult = i; - break; - } - } - - std::lock_guard lock(m_confirmMutex); - m_confirmDone = true; -} diff --git a/src/lib_gui/qt/view/QtMainView.h b/src/lib_gui/qt/view/QtMainView.h index f4019b63..df2a0edf 100644 --- a/src/lib_gui/qt/view/QtMainView.h +++ b/src/lib_gui/qt/view/QtMainView.h @@ -29,6 +29,8 @@ public: QtMainView(); virtual ~QtMainView(); + QtMainWindow* getMainWindow() const; + // ViewLayout implementation virtual void addView(View* view); virtual void removeView(View* view); @@ -48,8 +50,6 @@ public: virtual void activateWindow(); virtual void updateRecentProjectMenu(); - virtual int confirm(const std::string& message, const std::vector& options); - private: void handleMessage(MessageForceEnterLicense* message); void handleMessage(MessageProjectEdit* message); @@ -65,8 +65,6 @@ private: void doUpdateRecentProjectMenu(); void doForceLicenseScreen(bool expired); - void doConfirm(const std::string& message, const std::vector& options); - std::shared_ptr m_window; std::vector m_views; @@ -78,11 +76,6 @@ private: QtThreadedFunctor<> m_activateWindowFunctor; QtThreadedFunctor<> m_updateRecentProjectMenuFunctor; QtThreadedFunctor m_forceLicenseScreenFunctor; - - QtThreadedFunctor&> m_confirmFunctor; - std::mutex m_confirmMutex; - bool m_confirmDone; - int m_confirmResult; }; #endif // QT_MAIN_VIEW_H diff --git a/src/lib_gui/qt/view/QtViewFactory.cpp b/src/lib_gui/qt/view/QtViewFactory.cpp index 466de1ec..fb143ef4 100644 --- a/src/lib_gui/qt/view/QtViewFactory.cpp +++ b/src/lib_gui/qt/view/QtViewFactory.cpp @@ -3,6 +3,7 @@ #include "component/view/GraphViewStyle.h" #include "qt/view/QtCodeView.h" #include "qt/view/QtCompositeView.h" +#include "qt/view/QtDialogView.h" #include "qt/view/QtGraphView.h" #include "qt/view/QtGraphViewStyleImpl.h" #include "qt/view/QtMainView.h" @@ -63,3 +64,8 @@ std::shared_ptr QtViewFactory::createUndoRedoView(ViewLayout* view { return View::createInitAndAddToLayout(viewLayout); } + +std::shared_ptr QtViewFactory::createDialogView(ViewLayout* viewLayout) const +{ + return std::make_shared(dynamic_cast(viewLayout)->getMainWindow()); +} diff --git a/src/lib_gui/qt/view/QtViewFactory.h b/src/lib_gui/qt/view/QtViewFactory.h index 385bdf7c..0b76fa86 100644 --- a/src/lib_gui/qt/view/QtViewFactory.h +++ b/src/lib_gui/qt/view/QtViewFactory.h @@ -19,6 +19,8 @@ public: virtual std::shared_ptr createSearchView(ViewLayout* viewLayout) const; virtual std::shared_ptr createStatusBarView(ViewLayout* viewLayout) const; virtual std::shared_ptr createUndoRedoView(ViewLayout* viewLayout) const; + + virtual std::shared_ptr createDialogView(ViewLayout* viewLayout) const; }; #endif // QT_VIEW_FACTORY_H diff --git a/src/lib_gui/qt/window/QtIndexingDialog.cpp b/src/lib_gui/qt/window/QtIndexingDialog.cpp new file mode 100644 index 00000000..2773ee29 --- /dev/null +++ b/src/lib_gui/qt/window/QtIndexingDialog.cpp @@ -0,0 +1,397 @@ +#include "qt/window/QtIndexingDialog.h" + +#include +#include +#include +#include + +#include "qt/utility/utilityQt.h" +#include "qt/element/QtProgressBar.h" +#include "utility/messaging/type/MessageInterruptTasks.h" +#include "utility/ResourcePaths.h" +#include "utility/utility.h" + +QtIndexingDialog::QtIndexingDialog(QWidget* parent) + : QtWindow(parent) + , m_type(DIALOG_MESSAGE) + , m_top(nullptr) + , m_topRatio(0) + , m_progressBar(nullptr) + , m_percentLabel(nullptr) + , m_messageLabel(nullptr) + , m_filePathLabel(nullptr) + , m_errorLabel(nullptr) + , m_sizeHint(QSize(450, 450)) + , m_callback([](bool){}) +{ + // setWindowFlags(Qt::WindowStaysOnTopHint); +} + +QSize QtIndexingDialog::sizeHint() const +{ + return m_sizeHint; +} + +QtIndexingDialog::DialogType QtIndexingDialog::getType() const +{ + return m_type; +} + +void QtIndexingDialog::setupStart(size_t cleanFileCount, size_t indexFileCount, std::function callback) +{ + QBoxLayout* layout = createLayout(); + + addTitle("Start Indexing", layout); + layout->addSpacing(5); + + if (cleanFileCount) + { + QLabel* cleanLabel = new QLabel("Clear: " + QString::number(cleanFileCount) + " File" + (cleanFileCount > 1 ? "s" : "")); + cleanLabel->setObjectName("message"); + cleanLabel->setAlignment(Qt::AlignRight); + layout->addWidget(cleanLabel, 0, Qt::AlignRight); + } + + addMessageLabel(layout); + updateMessage("Index: " + QString::number(indexFileCount) + " File" + (indexFileCount > 1 ? "s" : "")); + + layout->addStretch(); + + addButtons(layout); + updateNextButton("Start"); + updateCloseButton("Cancel"); + + m_sizeHint = QSize(350, 250); + m_callback = callback; + + finishSetup(); +} + +void QtIndexingDialog::setupProgress() +{ + setType(DIALOG_PROGRESS); + + QBoxLayout* layout = createLayout(); + + addTopAndProgressBar(0.5); + addTitle("Clearing", layout); + addMessageLabel(layout); + + layout->addStretch(); + + m_sizeHint = QSize(350, 350); + + m_progressBar->showUnknownProgressAnimated(); + + setCancelAble(false); + + finishSetup(); +} + +void QtIndexingDialog::setupIndexing() +{ + setType(DIALOG_INDEXING); + + QBoxLayout* layout = createLayout(); + + addTopAndProgressBar(0.38); + addTitle("Indexing Files", layout); + + addPercentLabel(layout); + addMessageLabel(layout); + addFilePathLabel(layout); + + layout->addSpacing(12); + addErrorLabel(layout); + + layout->addStretch(); + + addButtons(layout); + setNextVisible(false); + updateCloseButton("Stop"); + + m_sizeHint = QSize(350, 350); + + finishSetup(); +} + +void QtIndexingDialog::setupReport(size_t fileCount, size_t totalFileCount, float time) +{ + QBoxLayout* layout = createLayout(); + + addTitle("Finished Indexing", layout); + layout->addSpacing(5); + + addMessageLabel(layout); + updateMessage( + QString::number(fileCount) + "/" + QString::number(totalFileCount) + " File" + (totalFileCount > 1 ? "s" : "") + ); + + QLabel* timeLabel = new QLabel("Total Time: " + QString::fromStdString(utility::timeToString(time))); + timeLabel->setObjectName("message"); + timeLabel->setAlignment(Qt::AlignRight); + layout->addWidget(timeLabel, 0, Qt::AlignRight); + + layout->addSpacing(12); + addErrorLabel(layout); + + layout->addStretch(); + + addButtons(layout); + updateNextButton("OK"); + setCloseVisible(false); + + m_sizeHint = QSize(400, 260); + + if (fileCount != totalFileCount) + { + updateTitle("Interrupted Indexing"); + } + else + { + addFlag(); + } + + finishSetup(); +} + +void QtIndexingDialog::updateMessage(QString message) +{ + if (m_messageLabel) + { + m_messageLabel->setText(message); + } +} + +void QtIndexingDialog::updateIndexingProgress(size_t fileCount, size_t totalFileCount, std::string sourcePath) +{ + updateMessage(QString::number(fileCount) + "/" + QString::number(totalFileCount) + " File" + (totalFileCount > 1 ? "s" : "")); + + if (fileCount > 0) + { + fileCount--; + } + + size_t percent = fileCount * 100 / totalFileCount; + m_progressBar->showProgress(percent); + m_percentLabel->setText(QString::number(percent) + "% Progress"); + m_sourcePath = QString::fromStdString(sourcePath); + setGeometries(); +} + +void QtIndexingDialog::updateErrorCount(size_t errorCount, size_t fatalCount) +{ + if (m_errorLabel && errorCount) + { + QString str = QString::number(errorCount) + " Error"; + if (errorCount > 1) + { + str += "s"; + } + + if (fatalCount) + { + str += " (" + QString::number(fatalCount) + " Fatal)"; + } + + m_errorLabel->setText(str); + m_errorLabel->show(); + } +} + +void QtIndexingDialog::resizeEvent(QResizeEvent* event) +{ + QtWindow::resizeEvent(event); + + setGeometries(); +} + +void QtIndexingDialog::handleNext() +{ + if (m_type == DIALOG_MESSAGE) + { + m_callback(true); + } + + QtWindow::handleNext(); +} + +void QtIndexingDialog::handleClose() +{ + if (m_type == DIALOG_MESSAGE) + { + m_callback(false); + } + + if (m_type == DIALOG_INDEXING) + { + MessageInterruptTasks().dispatch(); + return; + } + + QtWindow::handleClose(); +} + +void QtIndexingDialog::setType(DialogType type) +{ + m_type = type; +} + +QBoxLayout* QtIndexingDialog::createLayout() +{ + m_window->setStyleSheet( + m_window->styleSheet() + + "#window { " + "background: #2E3C86;" + "border: none;" + "}" + ); + + setStyleSheet(( + utility::getStyleSheet(ResourcePaths::getGuiPath() + "window/window.css") + + utility::getStyleSheet(ResourcePaths::getGuiPath() + "indexing_dialog/indexing_dialog.css") + ).c_str()); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setContentsMargins(20, 20, 20, 0); + layout->setSpacing(3); + + m_content->setLayout(layout); + + return layout; +} + +void QtIndexingDialog::addTopAndProgressBar(float topRatio) +{ + m_topRatio = topRatio; + + m_top = new QWidget(m_window); + m_top->setObjectName("topHalf"); + m_top->setGeometry(0, 0, m_window->size().width(), m_window->size().height() * topRatio); + m_top->show(); + m_top->lower(); + + m_progressBar = new QtProgressBar(m_window); + m_progressBar->setGeometry(0, m_window->size().height() * topRatio - 5, m_window->size().width(), 10); +} + +void QtIndexingDialog::addTitle(QString title, QBoxLayout* layout) +{ + m_title = new QLabel(title, this); + m_title->setObjectName("title"); + m_title->setAlignment(Qt::AlignRight | Qt::AlignBottom); + + if (m_top) + { + m_title->show(); + } + else + { + layout->addWidget(m_title, 0, Qt::AlignRight); + } +} + +void QtIndexingDialog::addPercentLabel(QBoxLayout* layout) +{ + m_percentLabel = new QLabel("0% Progress"); + m_percentLabel->setObjectName("percent"); + layout->addWidget(m_percentLabel, 0, Qt::AlignRight); +} + +void QtIndexingDialog::addMessageLabel(QBoxLayout* layout) +{ + m_messageLabel = new QLabel(); + m_messageLabel->setObjectName("message"); + m_messageLabel->setAlignment(Qt::AlignRight); + layout->addWidget(m_messageLabel, 0, Qt::AlignRight); +} + +void QtIndexingDialog::addFilePathLabel(QBoxLayout* layout) +{ + m_filePathLabel = new QLabel(); + m_filePathLabel->setObjectName("filePath"); + m_filePathLabel->setAlignment(Qt::AlignRight); + layout->addWidget(m_filePathLabel); +} + +void QtIndexingDialog::addErrorLabel(QBoxLayout* layout) +{ + m_errorLabel = new QPushButton(); + m_errorLabel->setObjectName("errorCount"); + m_errorLabel->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + + std::string text = ResourcePaths::getGuiPath() + "indexing_dialog/error.png"; + m_errorLabel->setIcon(QPixmap(text.c_str())); + + layout->addWidget(m_errorLabel, 0, Qt::AlignRight); + m_errorLabel->hide(); +} + +void QtIndexingDialog::addButtons(QBoxLayout* layout) +{ + m_nextButton = new QPushButton("Next"); + m_nextButton->setObjectName("windowButton"); + connect(m_nextButton, SIGNAL(clicked()), this, SLOT(handleNextPress())); + + m_closeButton = new QPushButton("Cancel"); + m_closeButton->setObjectName("windowButton"); + connect(m_closeButton, SIGNAL(clicked()), this, SLOT(handleClosePress())); + + QHBoxLayout* buttons = new QHBoxLayout(); + buttons->addWidget(m_closeButton); + buttons->addStretch(); + buttons->addWidget(m_nextButton); + + layout->addLayout(buttons); + + setNextDefault(true); +} + +void QtIndexingDialog::addFlag() +{ + QtDeviceScaledPixmap flag((ResourcePaths::getGuiPath() + "indexing_dialog/flag.png").c_str()); + flag.scaleToWidth(120); + + QLabel* flagLabel = new QLabel(this); + flagLabel->setPixmap(flag.pixmap()); + flagLabel->resize(flag.width(), flag.height()); + flagLabel->move(15, 75); + flagLabel->show(); +} + +void QtIndexingDialog::setGeometries() +{ + if (m_top) + { + QMargins margins = m_content->layout()->contentsMargins(); + margins.setTop(m_window->size().height() * m_topRatio + 10); + m_content->layout()->setContentsMargins(margins); + + m_top->setGeometry(0, 0, m_window->size().width(), m_window->size().height() * m_topRatio); + + m_title->setGeometry( + margins.left(), + m_window->size().height() * m_topRatio - 50, + m_window->size().width() - margins.left() - margins.right(), + 40 + ); + } + + if (m_progressBar) + { + m_progressBar->setGeometry(0, m_window->size().height() * m_topRatio - 5, m_window->size().width(), 10); + } + + if (m_filePathLabel) + { + m_filePathLabel->setText(m_filePathLabel->fontMetrics().elidedText( + m_sourcePath, Qt::ElideLeft, m_filePathLabel->width())); + } +} + +void QtIndexingDialog::finishSetup() +{ + setGeometries(); + + setupDone(); +} diff --git a/src/lib_gui/qt/window/QtIndexingDialog.h b/src/lib_gui/qt/window/QtIndexingDialog.h new file mode 100644 index 00000000..3708f11f --- /dev/null +++ b/src/lib_gui/qt/window/QtIndexingDialog.h @@ -0,0 +1,77 @@ +#ifndef QT_INDEXING_WIZARD_WINDOW_H +#define QT_INDEXING_WIZARD_WINDOW_H + +#include "qt/window/QtWindow.h" + +class QLabel; +class QtProgressBar; + +class QtIndexingDialog + : public QtWindow +{ + Q_OBJECT + +public: + enum DialogType + { + DIALOG_MESSAGE, + DIALOG_PROGRESS, + DIALOG_INDEXING + }; + + QtIndexingDialog(QWidget* parent = 0); + QSize sizeHint() const override; + + DialogType getType() const; + + void setupStart(size_t cleanFileCount, size_t indexFileCount, std::function callback); + void setupProgress(); + void setupIndexing(); + void setupReport(size_t fileCount, size_t totalFileCount, float time); + + void updateMessage(QString message); + void updateIndexingProgress(size_t fileCount, size_t totalFileCount, std::string sourcePath); + void updateErrorCount(size_t errorCount, size_t fatalCount); + +protected: + void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE; + + virtual void handleNext() override; + virtual void handleClose() override; + +private: + void setType(DialogType type); + + QBoxLayout* createLayout(); + void addTopAndProgressBar(float topRatio); + void addTitle(QString title, QBoxLayout* layout); + + void addPercentLabel(QBoxLayout* layout); + void addMessageLabel(QBoxLayout* layout); + void addFilePathLabel(QBoxLayout* layout); + void addErrorLabel(QBoxLayout* layout); + + void addButtons(QBoxLayout* layout); + void addFlag(); + + void setGeometries(); + void finishSetup(); + + DialogType m_type; + + QWidget* m_top; + float m_topRatio; + QtProgressBar* m_progressBar; + + QLabel* m_percentLabel; + QLabel* m_messageLabel; + QLabel* m_filePathLabel; + QPushButton* m_errorLabel; + + QSize m_sizeHint; + + std::function m_callback; + QString m_sourcePath; +}; + +#endif // QT_INDEXING_WIZARD_WINDOW_H diff --git a/src/lib_gui/qt/window/QtMainWindow.cpp b/src/lib_gui/qt/window/QtMainWindow.cpp index 97a9c3f7..e1fb5386 100644 --- a/src/lib_gui/qt/window/QtMainWindow.cpp +++ b/src/lib_gui/qt/window/QtMainWindow.cpp @@ -287,7 +287,7 @@ void QtMainWindow::forceEnterLicense(bool expired) bool QtMainWindow::event(QEvent* event) { - if (event->type() == QEvent::WindowActivate) + if (isEnabled() && event->type() == QEvent::WindowActivate) { MessageWindowFocus().dispatch(); } @@ -499,6 +499,34 @@ void QtMainWindow::resetZoom() MessageResetZoom().dispatch(); } +void QtMainWindow::openRecentProject() +{ + QAction *action = qobject_cast(sender()); + if (action) + { + openProject(action->data().toString()); + } +} + +void QtMainWindow::updateRecentProjectMenu() +{ + std::vector recentProjects = ApplicationSettings::getInstance()->getRecentProjects(); + for (int i = 0; i < ApplicationSettings::getInstance()->getMaxRecentProjectsCount(); i++) + { + if ((size_t)i < recentProjects.size() && recentProjects[i].exists()) + { + FilePath project = recentProjects[i]; + m_recentProjectAction[i]->setVisible(true); + m_recentProjectAction[i]->setText(FileSystem::fileName(project.str()).c_str()); + m_recentProjectAction[i]->setData(project.str().c_str()); + } + else + { + m_recentProjectAction[i]->setVisible(false); + } + } +} + void QtMainWindow::toggleView(View* view, bool fromMenu) { DockWidget* dock = getDockWidgetForView(view); @@ -513,6 +541,11 @@ void QtMainWindow::toggleView(View* view, bool fromMenu) } } +void QtMainWindow::toggleShowDockWidgetTitleBars() +{ + setShowDockWidgetTitleBars(!m_showDockWidgetTitleBars); +} + void QtMainWindow::setupProjectMenu() { QMenu *menu = new QMenu(tr("&Project"), this); @@ -551,39 +584,6 @@ void QtMainWindow::setupProjectMenu() menu->addAction(tr("E&xit"), QCoreApplication::instance(), SLOT(quit()), QKeySequence::Quit); } -void QtMainWindow::openRecentProject() -{ - QAction *action = qobject_cast(sender()); - if (action) - { - openProject(action->data().toString()); - } -} - -void QtMainWindow::updateRecentProjectMenu() -{ - std::vector recentProjects = ApplicationSettings::getInstance()->getRecentProjects(); - for (int i = 0; i < ApplicationSettings::getInstance()->getMaxRecentProjectsCount(); i++) - { - if ((size_t)i < recentProjects.size() && recentProjects[i].exists()) - { - FilePath project = recentProjects[i]; - m_recentProjectAction[i]->setVisible(true); - m_recentProjectAction[i]->setText(FileSystem::fileName(project.str()).c_str()); - m_recentProjectAction[i]->setData(project.str().c_str()); - } - else - { - m_recentProjectAction[i]->setVisible(false); - } - } -} - -void QtMainWindow::toggleShowDockWidgetTitleBars() -{ - setShowDockWidgetTitleBars(!m_showDockWidgetTitleBars); -} - void QtMainWindow::setupEditMenu() { QMenu *menu = new QMenu(tr("&Edit"), this); diff --git a/src/lib_gui/qt/window/QtMainWindow.h b/src/lib_gui/qt/window/QtMainWindow.h index ff383b69..b8825a17 100644 --- a/src/lib_gui/qt/window/QtMainWindow.h +++ b/src/lib_gui/qt/window/QtMainWindow.h @@ -47,6 +47,7 @@ private: size_t m_forwardButton; }; + class MouseWheelFilter : public QObject { @@ -111,7 +112,6 @@ public slots: void newProjectFromSolution(const std::string& ideId, const std::string& solutionPath); void openProject(const QString &path = QString()); void editProject(); - void openRecentProject(); void find(); void findFulltext(); @@ -129,10 +129,11 @@ public slots: void zoomOut(); void resetZoom(); - void toggleView(View* view, bool fromMenu); - + void openRecentProject(); void updateRecentProjectMenu(); + void toggleView(View* view, bool fromMenu); + private slots: void toggleShowDockWidgetTitleBars(); diff --git a/src/lib_gui/qt/window/QtWindow.cpp b/src/lib_gui/qt/window/QtWindow.cpp index 0d50a97d..27a72795 100644 --- a/src/lib_gui/qt/window/QtWindow.cpp +++ b/src/lib_gui/qt/window/QtWindow.cpp @@ -20,7 +20,6 @@ QtWindow::QtWindow(QWidget* parent) , m_closeButton(nullptr) , m_cancelAble(true) , m_scrollAble(false) - , m_showAsPopup(false) , m_hasLogo(false) , m_mousePressedInWindow(false) { @@ -84,6 +83,7 @@ QSize QtWindow::sizeHint() const void QtWindow::setup() { setStyleSheet(utility::getStyleSheet(ResourcePaths::getGuiPath() + "window/window.css").c_str()); + QVBoxLayout* layout = new QVBoxLayout(); layout->setContentsMargins(25, 30, 25, 0); @@ -140,13 +140,6 @@ void QtWindow::setup() m_content->setLayout(layout); - if (m_showAsPopup) - { - updateNextButton("Ok"); - setCloseVisible(false); - setPreviousVisible(false); - } - setupDone(); } @@ -162,21 +155,11 @@ void QtWindow::setScrollAble(bool scrollAble) m_scrollAble = scrollAble; } -void QtWindow::setShowAsPopup(bool showAsPopup) -{ - m_showAsPopup = showAsPopup; -} - bool QtWindow::isScrollAble() const { return m_scrollAble; } -bool QtWindow::isPopup() const -{ - return m_showAsPopup; -} - void QtWindow::updateTitle(QString title) { if (m_title) @@ -249,6 +232,30 @@ void QtWindow::setCloseVisible(bool visible) } } +void QtWindow::setNextDefault(bool isDefault) +{ + if (m_nextButton) + { + m_nextButton->setDefault(isDefault); + } +} + +void QtWindow::setPreviousDefault(bool isDefault) +{ + if (m_previousButton) + { + m_previousButton->setDefault(isDefault); + } +} + +void QtWindow::setCloseDefault(bool isDefault) +{ + if (m_closeButton) + { + m_closeButton->setDefault(isDefault); + } +} + void QtWindow::showWindow() { show(); @@ -289,14 +296,50 @@ void QtWindow::resizeEvent(QResizeEvent *event) m_window->move(5, displacement + 10); } -void QtWindow::keyPressEvent(QKeyEvent *event) +void QtWindow::keyPressEvent(QKeyEvent* event) { if (m_cancelAble && event->key() == Qt::Key_Escape) { - emit canceled(); + handleClose(); return; } + std::vector buttons; + if (m_nextButton && m_nextButton->isVisible()) buttons.push_back(m_nextButton); + if (m_closeButton && m_closeButton->isVisible()) buttons.push_back(m_closeButton); + if (m_previousButton && m_previousButton->isVisible()) buttons.push_back(m_previousButton); + + if (event->key() == Qt::Key_Return) + { + for (QPushButton* button : buttons) + { + if (button->isDefault()) + { + button->animateClick(); + return; + } + } + } + + if (event->key() == Qt::Key_Tab) + { + for (size_t i = 0; i < buttons.size(); i++) + { + if (buttons[i]->isDefault()) + { + buttons[i]->setDefault(false); + buttons[(i + 1) % buttons.size()]->setDefault(true); + return; + } + } + + if (buttons.size()) + { + buttons[0]->setDefault(true); + return; + } + } + QWidget::keyPressEvent(event); } diff --git a/src/lib_gui/qt/window/QtWindow.h b/src/lib_gui/qt/window/QtWindow.h index 5f7d8166..a452ca7b 100644 --- a/src/lib_gui/qt/window/QtWindow.h +++ b/src/lib_gui/qt/window/QtWindow.h @@ -26,10 +26,8 @@ public: void setCancelAble(bool cancelAble); void setScrollAble(bool scrollAble); - void setShowAsPopup(bool showAsPopup); bool isScrollAble() const; - bool isPopup() const; void updateTitle(QString title); void updateNextButton(QString text); @@ -43,10 +41,15 @@ public: void setPreviousVisible(bool visible); void setCloseVisible(bool visible); + void setNextDefault(bool isDefault); + void setPreviousDefault(bool isDefault); + void setCloseDefault(bool isDefault); + // QtWindowStackElement implementation virtual void showWindow() override; virtual void hideWindow() override; + signals: void finished(); void canceled(); @@ -88,7 +91,6 @@ private slots: private: bool m_cancelAble; bool m_scrollAble; - bool m_showAsPopup; bool m_hasLogo; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h index dec0ec74..9d93a042 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h @@ -47,8 +47,6 @@ private: QtProjectWizzardWindow* createWindowWithSummary( std::function func); - void connectShowFiles(QtProjectWizzardContent* content); - QtWindowStack m_windowStack; std::shared_ptr m_settings; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp index 3beb71f2..8dc81fee 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp @@ -72,12 +72,6 @@ void QtProjectWizzardWindow::windowReady() void QtProjectWizzardWindow::handleNext() { - if (isPopup()) - { - hide(); - emit next(); - } - m_content->save(); if (m_content->check()) diff --git a/src/test/TaskSchedulerTestSuite.h b/src/test/TaskSchedulerTestSuite.h index faaf2e9f..3b7becd9 100644 --- a/src/test/TaskSchedulerTestSuite.h +++ b/src/test/TaskSchedulerTestSuite.h @@ -41,6 +41,7 @@ public: TS_ASSERT_EQUALS(3, task.exitCallOrder); TS_ASSERT_EQUALS(0, task.interruptCallOrder); TS_ASSERT_EQUALS(0, task.revertCallOrder); + TS_ASSERT_EQUALS(0, task.abortCallOrder); } void test_scheduled_tasks_get_processed_with_callbacks_in_correct_order(void) @@ -63,6 +64,7 @@ public: TS_ASSERT_EQUALS(3, task->exitCallOrder); TS_ASSERT_EQUALS(0, task->interruptCallOrder); TS_ASSERT_EQUALS(0, task->revertCallOrder); + TS_ASSERT_EQUALS(0, task->abortCallOrder); } void test_scheduled_tasks_get_interrupted_with_callbacks_in_correct_order(void) @@ -87,6 +89,7 @@ public: TS_ASSERT_EQUALS(order - 1, task->interruptCallOrder); TS_ASSERT_EQUALS(order, task->exitCallOrder); TS_ASSERT_EQUALS(0, task->revertCallOrder); + TS_ASSERT_EQUALS(0, task->abortCallOrder); } void test_sequential_task_group_to_process_tasks_in_correct_order(void) @@ -114,12 +117,14 @@ public: TS_ASSERT_EQUALS(3, task1->exitCallOrder); TS_ASSERT_EQUALS(0, task1->interruptCallOrder); TS_ASSERT_EQUALS(0, task1->revertCallOrder); + TS_ASSERT_EQUALS(0, task1->abortCallOrder); TS_ASSERT_EQUALS(4, task2->enterCallOrder); TS_ASSERT_EQUALS(5, task2->updateCallOrder); TS_ASSERT_EQUALS(6, task2->exitCallOrder); TS_ASSERT_EQUALS(0, task2->interruptCallOrder); TS_ASSERT_EQUALS(0, task2->revertCallOrder); + TS_ASSERT_EQUALS(0, task2->abortCallOrder); } void test_sequential_task_group_to_interrupt_and_revert_tasks_in_correct_order(void) @@ -148,13 +153,15 @@ public: TS_ASSERT_EQUALS(2, task1->updateCallOrder); TS_ASSERT_EQUALS(3, task1->exitCallOrder); TS_ASSERT_EQUALS(0, task1->interruptCallOrder); - TS_ASSERT_EQUALS(order, task1->revertCallOrder); + TS_ASSERT_EQUALS(order - 2, task1->revertCallOrder); + TS_ASSERT_EQUALS(0, task1->abortCallOrder); TS_ASSERT_EQUALS(4, task2->enterCallOrder); TS_ASSERT_EQUALS(order - 3, task2->updateCallOrder); - TS_ASSERT_EQUALS(order - 2, task2->interruptCallOrder); - TS_ASSERT_EQUALS(order - 1, task2->exitCallOrder); + TS_ASSERT_EQUALS(order - 1, task2->interruptCallOrder); + TS_ASSERT_EQUALS(order, task2->exitCallOrder); TS_ASSERT_EQUALS(0, task2->revertCallOrder); + TS_ASSERT_EQUALS(0, task2->abortCallOrder); } void test_sequential_task_group_to_interrupt_and_revert_nested_task_groups_in_correct_order(void) @@ -193,25 +200,29 @@ public: TS_ASSERT_EQUALS(2, task1->updateCallOrder); TS_ASSERT_EQUALS(3, task1->exitCallOrder); TS_ASSERT_EQUALS(0, task1->interruptCallOrder); - TS_ASSERT_EQUALS(order, task1->revertCallOrder); + TS_ASSERT_EQUALS(order - 3, task1->revertCallOrder); + TS_ASSERT_EQUALS(0, task1->abortCallOrder); TS_ASSERT_EQUALS(4, task2->enterCallOrder); TS_ASSERT_EQUALS(5, task2->updateCallOrder); TS_ASSERT_EQUALS(6, task2->exitCallOrder); TS_ASSERT_EQUALS(0, task2->interruptCallOrder); - TS_ASSERT_EQUALS(order - 1, task2->revertCallOrder); + TS_ASSERT_EQUALS(order - 4, task2->revertCallOrder); + TS_ASSERT_EQUALS(0, task2->abortCallOrder); TS_ASSERT_EQUALS(7, task3->enterCallOrder); - TS_ASSERT_EQUALS(order - 4, task3->updateCallOrder); - TS_ASSERT_EQUALS(order - 3, task3->interruptCallOrder); - TS_ASSERT_EQUALS(order - 2, task3->exitCallOrder); + TS_ASSERT_EQUALS(order - 5, task3->updateCallOrder); + TS_ASSERT_EQUALS(order - 2, task3->interruptCallOrder); + TS_ASSERT_EQUALS(order - 1, task3->exitCallOrder); TS_ASSERT_EQUALS(0, task3->revertCallOrder); + TS_ASSERT_EQUALS(0, task3->abortCallOrder); TS_ASSERT_EQUALS(0, task4->enterCallOrder); TS_ASSERT_EQUALS(0, task4->updateCallOrder); TS_ASSERT_EQUALS(0, task4->exitCallOrder); TS_ASSERT_EQUALS(0, task4->interruptCallOrder); TS_ASSERT_EQUALS(0, task4->revertCallOrder); + TS_ASSERT_EQUALS(order, task4->abortCallOrder); } void test_task_scheduling_within_task_processing() @@ -255,6 +266,7 @@ private: , exitCallOrder(0) , interruptCallOrder(0) , revertCallOrder(0) + , abortCallOrder(0) { } @@ -297,6 +309,11 @@ private: revertCallOrder = ++orderCount; } + virtual void abort() + { + abortCallOrder = ++orderCount; + } + int& orderCount; int updateCount; @@ -305,6 +322,7 @@ private: int exitCallOrder; int interruptCallOrder; int revertCallOrder; + int abortCallOrder; }; class TestTaskDispatch: public TestTask diff --git a/src/trial/data/parser/cxx/TaskParseCxx.cpp b/src/trial/data/parser/cxx/TaskParseCxx.cpp index bafada8f..4533f438 100644 --- a/src/trial/data/parser/cxx/TaskParseCxx.cpp +++ b/src/trial/data/parser/cxx/TaskParseCxx.cpp @@ -4,7 +4,8 @@ TaskParseCxx::TaskParseCxx( PersistentStorage* storage, std::shared_ptr storageMutex, std::shared_ptr fileRegister, - const Parser::Arguments& arguments + const Parser::Arguments& arguments, + DialogView* dialogView ) { } @@ -34,3 +35,7 @@ void TaskParseCxx::interrupt() void TaskParseCxx::revert() { } + +void TaskParseCxx::abort() +{ +} diff --git a/src/trial/data/parser/cxx/TaskParseWrapper.cpp b/src/trial/data/parser/cxx/TaskParseWrapper.cpp index 5a156806..1bb77cd2 100644 --- a/src/trial/data/parser/cxx/TaskParseWrapper.cpp +++ b/src/trial/data/parser/cxx/TaskParseWrapper.cpp @@ -5,7 +5,8 @@ TaskParseWrapper::TaskParseWrapper( PersistentStorage* storage, - std::shared_ptr fileRegister + std::shared_ptr fileRegister, + DialogView* dialogView ) : m_storage(storage) { @@ -33,7 +34,7 @@ void TaskParseWrapper::exit() m_storage->finishParsing(); - MessageFinishedParsing(0, 0, 0).dispatch(); + MessageFinishedParsing().dispatch(); } void TaskParseWrapper::interrupt() @@ -45,3 +46,10 @@ void TaskParseWrapper::revert() { m_task->revert(); } + +void TaskParseWrapper::abort() +{ + m_task->abort(); + + MessageFinishedParsing().dispatch(); +} diff --git a/src/trial/data/parser/java/TaskParseJava.cpp b/src/trial/data/parser/java/TaskParseJava.cpp index 4a561824..c22ac081 100644 --- a/src/trial/data/parser/java/TaskParseJava.cpp +++ b/src/trial/data/parser/java/TaskParseJava.cpp @@ -4,7 +4,8 @@ TaskParseJava::TaskParseJava( PersistentStorage* storage, std::shared_ptr storageMutex, std::shared_ptr fileRegister, - const Parser::Arguments& arguments + const Parser::Arguments& arguments, + DialogView* dialogView ) { } @@ -29,3 +30,7 @@ void TaskParseJava::interrupt() void TaskParseJava::revert() { } + +void TaskParseJava::abort() +{ +} diff --git a/src/trial/main.cpp b/src/trial/main.cpp index 8bc9fd2b..585bc36a 100644 --- a/src/trial/main.cpp +++ b/src/trial/main.cpp @@ -53,6 +53,7 @@ int main(int argc, char *argv[]) QtNetworkFactory networkFactory; utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf"); + utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".ttf"); Application::createInstance(version, &viewFactory, &networkFactory); ScopedFunctor f([](){