diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 73e8fe2b..36819a57 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -192,8 +192,8 @@ add_files( data/TaskFinishParsing.h data/TaskInjectStorage.cpp data/TaskInjectStorage.h - data/TaskShowDialogView.cpp - data/TaskShowDialogView.h + data/TaskShowStatusDialog.cpp + data/TaskShowStatusDialog.h settings/ApplicationSettings.cpp settings/ApplicationSettings.h diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 892a828b..e8f935f6 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -7,7 +7,7 @@ #include "data/StorageProvider.h" #include "data/PersistentStorage.h" #include "data/TaskCleanStorage.h" -#include "data/TaskShowDialogView.h" +#include "data/TaskShowStatusDialog.h" #include "data/TaskFinishParsing.h" #include "data/TaskInjectStorage.h" #include "settings/ApplicationSettings.h" @@ -407,7 +407,7 @@ void Project::buildIndex(const std::set& filesToClean, const std::set< ); taskSequential->addTask( // we don't need to hide this dialog again, because it's overridden by other dialogs later on. - std::make_shared("Finish Indexing", "Saving\nRemaining Data", m_dialogView) + std::make_shared("Finish Indexing", "Saving\nRemaining Data", m_dialogView) ); taskSequential->addTask( diff --git a/src/lib/component/view/DialogView.cpp b/src/lib/component/view/DialogView.cpp index 70db6f3c..7d8eea30 100644 --- a/src/lib/component/view/DialogView.cpp +++ b/src/lib/component/view/DialogView.cpp @@ -9,7 +9,15 @@ DialogView::~DialogView() { } -void DialogView::showProgressDialog(const std::string& title, const std::string& message) +void DialogView::showStatusDialog(const std::string& title, const std::string& message) +{ +} + +void DialogView::hideStatusDialog() +{ +} + +void DialogView::showProgressDialog(const std::string& title, const std::string& message, int progress) { } diff --git a/src/lib/component/view/DialogView.h b/src/lib/component/view/DialogView.h index f998cc63..ce36965d 100644 --- a/src/lib/component/view/DialogView.h +++ b/src/lib/component/view/DialogView.h @@ -21,7 +21,10 @@ public: DialogView(StorageAccess* storageAccess); virtual ~DialogView(); - virtual void showProgressDialog(const std::string& title, const std::string& message); + virtual void showStatusDialog(const std::string& title, const std::string& message); + virtual void hideStatusDialog(); + + virtual void showProgressDialog(const std::string& title, const std::string& message, int progress); virtual void hideProgressDialog(); virtual IndexMode startIndexingDialog( diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index 33750c62..6f7e25f8 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -323,7 +323,7 @@ std::set PersistentStorage::getReferencing(const std::set& f return referencing; } -void PersistentStorage::clearFileElements(const std::vector& filePaths) +void PersistentStorage::clearFileElements(const std::vector& filePaths, std::function updateStatusCallback) { TRACE(); @@ -331,7 +331,7 @@ void PersistentStorage::clearFileElements(const std::vector& filePaths if (!fileNodeIds.empty()) { - m_sqliteStorage.removeElementsWithLocationInFiles(fileNodeIds); + m_sqliteStorage.removeElementsWithLocationInFiles(fileNodeIds, updateStatusCallback); m_sqliteStorage.removeElements(fileNodeIds); m_sqliteStorage.removeErrorsInFiles(filePaths); diff --git a/src/lib/data/PersistentStorage.h b/src/lib/data/PersistentStorage.h index 7e76a7b9..c3c3caba 100644 --- a/src/lib/data/PersistentStorage.h +++ b/src/lib/data/PersistentStorage.h @@ -68,7 +68,7 @@ public: std::set getReferenced(const std::set& filePaths); std::set getReferencing(const std::set& filePaths); - void clearFileElements(const std::vector& filePaths); + void clearFileElements(const std::vector& filePaths, std::function updateStatusCallback); std::vector getInfoOnAllFiles() const; diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index 11694ac9..d18ba556 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -342,17 +342,32 @@ void SqliteStorage::removeElements(const std::vector& ids) ); } -void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fileIds) +void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fileIds, std::function updateStatusCallback) { + if (updateStatusCallback != nullptr) + { + updateStatusCallback(1); + } + // preparing executeStatement("DROP TABLE IF EXISTS main.element_id_to_clear;"); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(2); + } + executeStatement( "CREATE TABLE IF NOT EXISTS element_id_to_clear(" "id INTEGER NOT NULL, " "PRIMARY KEY(id));" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(3); + } + // store ids of all elements located in fileIds into element_id_to_clear executeStatement( "INSERT INTO element_id_to_clear " @@ -365,16 +380,31 @@ void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fil " GROUP BY (occurrence.element_id)" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(4); + } + // delete all edges in element_id_to_clear executeStatement( "DELETE FROM element WHERE element.id IN (SELECT element_id_to_clear.id FROM element_id_to_clear INNER JOIN edge ON (element_id_to_clear.id = edge.id))" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(22); + } + // delete all edges originating from element_id_to_clear executeStatement( "DELETE FROM element WHERE element.id IN (SELECT id FROM edge WHERE source_node_id IN (SELECT id FROM element_id_to_clear))" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(23); + } + // remove all edges from element_id_to_clear (they have been cleared by now and we can disregard them) executeStatement( "DELETE FROM element_id_to_clear WHERE id IN (" @@ -382,6 +412,11 @@ void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fil ")" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(24); + } + // remove all files from element_id_to_clear (they will be cleared later) executeStatement( "DELETE FROM element_id_to_clear WHERE id IN (" @@ -389,11 +424,21 @@ void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fil ")" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(25); + } + // delete source locations from fileIds (this also deletes the respective occurrences) executeStatement( "DELETE FROM source_location WHERE file_node_id IN (" + utility::join(utility::toStrings(fileIds), ',') + ");" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(34); + } + // remove all ids from element_id_to_clear that still have occurrences executeStatement( "DELETE FROM element_id_to_clear WHERE id IN (" @@ -401,6 +446,11 @@ void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fil ")" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(35); + } + // remove all ids from element_id_to_clear that still have an edge pointing to them executeStatement( "DELETE FROM element_id_to_clear WHERE id IN (" @@ -408,6 +458,11 @@ void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fil ")" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(44); + } + // delete all elements that are still listed in element_id_to_clear executeStatement( "DELETE FROM element WHERE id IN (" @@ -415,8 +470,18 @@ void SqliteStorage::removeElementsWithLocationInFiles(const std::vector& fil ")" ); + if (updateStatusCallback != nullptr) + { + updateStatusCallback(80); + } + // cleaning up executeStatement("DROP TABLE IF EXISTS main.element_id_to_clear;"); + + if (updateStatusCallback != nullptr) + { + updateStatusCallback(89); + } } void SqliteStorage::removeErrorsInFiles(const std::vector& filePaths) diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index d7519410..ba74b6d2 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -69,7 +69,7 @@ public: void removeElement(Id id); void removeElements(const std::vector& ids); - void removeElementsWithLocationInFiles(const std::vector& fileIds); + void removeElementsWithLocationInFiles(const std::vector& fileIds, std::function updateStatusCallback); void removeErrorsInFiles(const std::vector& filePaths); diff --git a/src/lib/data/TaskCleanStorage.cpp b/src/lib/data/TaskCleanStorage.cpp index 710b5933..57d742d6 100644 --- a/src/lib/data/TaskCleanStorage.cpp +++ b/src/lib/data/TaskCleanStorage.cpp @@ -16,7 +16,7 @@ TaskCleanStorage::TaskCleanStorage( void TaskCleanStorage::doEnter(std::shared_ptr blackboard) { - m_dialogView->showProgressDialog("Clearing Files", std::to_string(m_filePaths.size()) + " Files"); + m_dialogView->showStatusDialog("Clearing Files", std::to_string(m_filePaths.size()) + " Files"); m_start = utility::durationStart(); @@ -28,7 +28,15 @@ void TaskCleanStorage::doEnter(std::shared_ptr blackboard) Task::TaskState TaskCleanStorage::doUpdate(std::shared_ptr blackboard) { - m_storage->clearFileElements(m_filePaths); + DialogView* dialogView = m_dialogView; + m_storage->clearFileElements(m_filePaths, [=](int progress) + { + if (dialogView != nullptr) + { + dialogView->showProgressDialog("Clearing", std::to_string(m_filePaths.size()) + " Files", progress); + } + } + ); m_filePaths.clear(); diff --git a/src/lib/data/TaskFinishParsing.cpp b/src/lib/data/TaskFinishParsing.cpp index 7f64d3c7..359d90cf 100644 --- a/src/lib/data/TaskFinishParsing.cpp +++ b/src/lib/data/TaskFinishParsing.cpp @@ -33,13 +33,13 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr blackboa { TimePoint start = utility::durationStart(); - m_dialogView->showProgressDialog("Finish Indexing", "Optimizing database"); + m_dialogView->showStatusDialog("Finish Indexing", "Optimizing database"); m_storage->optimizeMemory(); - m_dialogView->showProgressDialog("Finish Indexing", "Building caches"); + m_dialogView->showStatusDialog("Finish Indexing", "Building caches"); m_storage->buildCaches(); - m_dialogView->hideProgressDialog(); + m_dialogView->hideStatusDialog(); MessageFinishedParsing().dispatch(); float time = utility::duration(start); diff --git a/src/lib/data/TaskShowDialogView.cpp b/src/lib/data/TaskShowDialogView.cpp deleted file mode 100644 index caf9f215..00000000 --- a/src/lib/data/TaskShowDialogView.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "data/TaskShowDialogView.h" - -#include "component/view/DialogView.h" - -TaskShowDialogView::TaskShowDialogView( - const std::string& title, - const std::string& message, - DialogView* dialogView -) - : m_title(title) - , m_message(message) - , m_dialogView(dialogView) -{ -} - -TaskShowDialogView::~TaskShowDialogView() -{ -} - -void TaskShowDialogView::doEnter(std::shared_ptr blackboard) -{ -} - -Task::TaskState TaskShowDialogView::doUpdate(std::shared_ptr blackboard) -{ - m_dialogView->showProgressDialog(m_title, m_message); - return STATE_SUCCESS; -} - -void TaskShowDialogView::doExit(std::shared_ptr blackboard) -{ -} - -void TaskShowDialogView::doReset(std::shared_ptr blackboard) -{ -} diff --git a/src/lib/data/TaskShowStatusDialog.cpp b/src/lib/data/TaskShowStatusDialog.cpp new file mode 100644 index 00000000..1401b423 --- /dev/null +++ b/src/lib/data/TaskShowStatusDialog.cpp @@ -0,0 +1,36 @@ +#include "data/TaskShowStatusDialog.h" + +#include "component/view/DialogView.h" + +TaskShowStatusDialog::TaskShowStatusDialog( + const std::string& title, + const std::string& message, + DialogView* dialogView +) + : m_title(title) + , m_message(message) + , m_dialogView(dialogView) +{ +} + +TaskShowStatusDialog::~TaskShowStatusDialog() +{ +} + +void TaskShowStatusDialog::doEnter(std::shared_ptr blackboard) +{ +} + +Task::TaskState TaskShowStatusDialog::doUpdate(std::shared_ptr blackboard) +{ + m_dialogView->showStatusDialog(m_title, m_message); + return STATE_SUCCESS; +} + +void TaskShowStatusDialog::doExit(std::shared_ptr blackboard) +{ +} + +void TaskShowStatusDialog::doReset(std::shared_ptr blackboard) +{ +} diff --git a/src/lib/data/TaskShowDialogView.h b/src/lib/data/TaskShowStatusDialog.h similarity index 74% rename from src/lib/data/TaskShowDialogView.h rename to src/lib/data/TaskShowStatusDialog.h index 4da4752a..972dd29b 100644 --- a/src/lib/data/TaskShowDialogView.h +++ b/src/lib/data/TaskShowStatusDialog.h @@ -1,5 +1,5 @@ -#ifndef TASK_SHOW_DIALOG_VIEW_H -#define TASK_SHOW_DIALOG_VIEW_H +#ifndef TASK_SHOW_STATUS_DIALOG_H +#define TASK_SHOW_STATUS_DIALOG_H #include @@ -7,17 +7,17 @@ class DialogView; -class TaskShowDialogView +class TaskShowStatusDialog : public Task { public: - TaskShowDialogView( + TaskShowStatusDialog( const std::string& title, const std::string& message, DialogView* dialogView ); - virtual ~TaskShowDialogView(); + virtual ~TaskShowStatusDialog(); private: virtual void doEnter(std::shared_ptr blackboard); @@ -30,4 +30,4 @@ private: DialogView* m_dialogView; }; -#endif // TASK_SHOW_DIALOG_VIEW_H +#endif // TASK_SHOW_STATUS_DIALOG_H diff --git a/src/lib_gui/qt/view/QtDialogView.cpp b/src/lib_gui/qt/view/QtDialogView.cpp index d08773ea..605db366 100644 --- a/src/lib_gui/qt/view/QtDialogView.cpp +++ b/src/lib_gui/qt/view/QtDialogView.cpp @@ -25,10 +25,52 @@ QtDialogView::~QtDialogView() m_resultReady = true; } -void QtDialogView::showProgressDialog(const std::string& title, const std::string& message) +void QtDialogView::showStatusDialog(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_STATUS) + { + m_windowStack.clearWindows(); + + window = createWindow(); + window->setupStatus(); + } + + window->updateTitle(title.c_str()); + window->updateMessage(message.c_str()); + + setUIBlocked(true); + } + ); +} + +void QtDialogView::hideStatusDialog() +{ + MessageStatus("", false, false).dispatch(); + + m_onQtThread( + [=]() + { + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (window && window->getType() == QtIndexingDialog::DIALOG_STATUS) + { + m_windowStack.popWindow(); + } + + setUIBlocked(false); + } + ); +} + +void QtDialogView::showProgressDialog(const std::string& title, const std::string& message, int progress) +{ + MessageStatus(title + ": " + message + " [" + std::to_string(progress) + "%]", false, true).dispatch(); + m_onQtThread( [=]() { @@ -43,6 +85,7 @@ void QtDialogView::showProgressDialog(const std::string& title, const std::strin window->updateTitle(title.c_str()); window->updateMessage(message.c_str()); + window->updateProgress(progress); setUIBlocked(true); } @@ -67,6 +110,7 @@ void QtDialogView::hideProgressDialog() ); } + DialogView::IndexMode QtDialogView::startIndexingDialog( size_t cleanFileCount, size_t indexFileCount, size_t totalFileCount, bool forceRefresh, bool needsFullRefresh) { @@ -211,7 +255,7 @@ void QtDialogView::handleMessage(MessageInterruptTasks* message) QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); if (window && window->getType() == QtIndexingDialog::DIALOG_INDEXING) { - showProgressDialog("Interrupting Indexing", "Waiting for indexer\nthreads to finish"); + showStatusDialog("Interrupting Indexing", "Waiting for indexer\nthreads to finish"); } } ); diff --git a/src/lib_gui/qt/view/QtDialogView.h b/src/lib_gui/qt/view/QtDialogView.h index 6a5d927d..9624a4d7 100644 --- a/src/lib_gui/qt/view/QtDialogView.h +++ b/src/lib_gui/qt/view/QtDialogView.h @@ -28,13 +28,16 @@ public: QtDialogView(QtMainWindow* mainWindow, StorageAccess* storageAccess); virtual ~QtDialogView(); - void showProgressDialog(const std::string& title, const std::string& message) override; - void hideProgressDialog() override; + virtual void showStatusDialog(const std::string& title, const std::string& message) override; + virtual void hideStatusDialog() override; - DialogView::IndexMode startIndexingDialog(size_t cleanFileCount, size_t indexFileCount, size_t totalFileCount, + virtual void showProgressDialog(const std::string& title, const std::string& message, int progress) override; + virtual void hideProgressDialog() override; + + virtual DialogView::IndexMode startIndexingDialog(size_t cleanFileCount, size_t indexFileCount, size_t totalFileCount, bool forceRefresh, bool needsFullRefresh) 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; + virtual void updateIndexingDialog(size_t fileCount, size_t totalFileCount, std::string sourcePath) override; + virtual void finishedIndexingDialog(size_t fileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo) override; int confirm(const std::string& message, const std::vector& options) override; diff --git a/src/lib_gui/qt/window/QtIndexingDialog.cpp b/src/lib_gui/qt/window/QtIndexingDialog.cpp index 4665280d..33399871 100644 --- a/src/lib_gui/qt/window/QtIndexingDialog.cpp +++ b/src/lib_gui/qt/window/QtIndexingDialog.cpp @@ -104,27 +104,6 @@ void QtIndexingDialog::setupStart( finishSetup(); } -void QtIndexingDialog::setupProgress() -{ - setType(DIALOG_PROGRESS); - - QBoxLayout* layout = createLayout(); - - addTopAndProgressBar(0.5); - addTitle("Clearing", layout); - addMessageLabel(layout); - - layout->addStretch(); - - m_sizeHint = QSize(350, 280); - - m_progressBar->showUnknownProgressAnimated(); - - setCancelAble(false); - - finishSetup(); -} - void QtIndexingDialog::setupIndexing() { setType(DIALOG_INDEXING); @@ -192,6 +171,47 @@ void QtIndexingDialog::setupReport(size_t fileCount, size_t totalFileCount, floa finishSetup(); } +void QtIndexingDialog::setupStatus() +{ + setType(DIALOG_STATUS); + + QBoxLayout* layout = createLayout(); + + addTopAndProgressBar(0.5); + addTitle("Status", layout); + addMessageLabel(layout); + + layout->addStretch(); + + m_sizeHint = QSize(350, 280); + + m_progressBar->showUnknownProgressAnimated(); + + setCancelAble(false); + + finishSetup(); +} + +void QtIndexingDialog::setupProgress() +{ + setType(DIALOG_PROGRESS); + + QBoxLayout* layout = createLayout(); + + addTopAndProgressBar(0.5); + addTitle("Progress", layout); + addPercentLabel(layout); + addMessageLabel(layout); + + layout->addStretch(); + + m_sizeHint = QSize(350, 280); + + setCancelAble(false); + + finishSetup(); +} + void QtIndexingDialog::updateMessage(QString message) { if (m_messageLabel) @@ -200,20 +220,27 @@ void QtIndexingDialog::updateMessage(QString message) } } +void QtIndexingDialog::updateProgress(int progress) +{ + int percent = std::min(std::max(progress, 0), 100); + + m_progressBar->showProgress(percent); + m_percentLabel->setText(QString::number(percent) + "% Progress"); + setGeometries(); +} + void QtIndexingDialog::updateIndexingProgress(size_t fileCount, size_t totalFileCount, std::string sourcePath) { updateMessage(QString::number(fileCount) + "/" + QString::number(totalFileCount) + " File" + (totalFileCount > 1 ? "s" : "")); - size_t percent = 0; + int progress = 0; if (totalFileCount > 0) { - percent = fileCount * 100 / totalFileCount; + progress = fileCount * 100 / totalFileCount; } - m_progressBar->showProgress(percent); - m_percentLabel->setText(QString::number(percent) + "% Progress"); m_sourcePath = QString::fromStdString(sourcePath); - setGeometries(); + updateProgress(progress); } void QtIndexingDialog::updateErrorCount(size_t errorCount, size_t fatalCount) diff --git a/src/lib_gui/qt/window/QtIndexingDialog.h b/src/lib_gui/qt/window/QtIndexingDialog.h index 139a6d03..455a2f78 100644 --- a/src/lib_gui/qt/window/QtIndexingDialog.h +++ b/src/lib_gui/qt/window/QtIndexingDialog.h @@ -18,6 +18,7 @@ public: enum DialogType { DIALOG_MESSAGE, + DIALOG_STATUS, DIALOG_PROGRESS, DIALOG_INDEXING }; @@ -29,11 +30,14 @@ public: void setupStart(size_t cleanFileCount, size_t indexFileCount, size_t totalFileCount, bool forceRefresh, bool needsFullRefresh, std::function callback); - void setupProgress(); void setupIndexing(); void setupReport(size_t fileCount, size_t totalFileCount, float time); + void setupStatus(); + void setupProgress(); + void updateMessage(QString message); + void updateProgress(int progress); void updateIndexingProgress(size_t fileCount, size_t totalFileCount, std::string sourcePath); void updateErrorCount(size_t errorCount, size_t fatalCount); diff --git a/src/lib_java/JavaProject.cpp b/src/lib_java/JavaProject.cpp index 6d24a10a..d636c6d4 100644 --- a/src/lib_java/JavaProject.cpp +++ b/src/lib_java/JavaProject.cpp @@ -97,9 +97,9 @@ std::shared_ptr JavaProject::createIndexerTask( if (!m_rootDirectories) { - getDialogView()->showProgressDialog("Preparing Project", "Gathering Root\nDirectories"); + getDialogView()->showStatusDialog("Preparing Project", "Gathering Root\nDirectories"); fetchRootDirectories(); - getDialogView()->hideProgressDialog(); + getDialogView()->hideStatusDialog(); } for (FilePath rootDirectory: *(m_rootDirectories.get()))