From 0f5bbe471cdcbe89a4ef48905cd549f2e9f77d62 Mon Sep 17 00:00:00 2001
From: Samuel Jones <samjones714@gmail.com>
Date: Thu, 1 Nov 2018 15:58:51 +0000
Subject: [PATCH] Re #23570 Working Progress bar and threading improvements

---
 MantidPlot/src/MultiTabScriptInterpreter.h    |  2 +-
 MantidPlot/src/ProjectRecovery.cpp            |  2 ++
 MantidPlot/src/ProjectRecovery.h              |  1 +
 .../ProjectRecoveryModel.cpp                  | 32 ++++++++++++-------
 .../ProjectRecoveryPresenter.cpp              | 11 +++++++
 .../ProjectRecoveryPresenter.h                |  3 ++
 .../ProjectRecoveryView.cpp                   | 23 +++++++------
 .../ProjectRecoveryGUIs/ProjectRecoveryView.h |  3 +-
 .../RecoveryFailureView.cpp                   | 18 ++++++++---
 .../ProjectRecoveryGUIs/RecoveryFailureView.h |  6 ++--
 MantidPlot/src/ScriptFileInterpreter.h        |  2 +-
 MantidPlot/src/ScriptingWindow.cpp            |  4 +--
 MantidPlot/src/ScriptingWindow.h              |  2 +-
 13 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/MantidPlot/src/MultiTabScriptInterpreter.h b/MantidPlot/src/MultiTabScriptInterpreter.h
index 00b51ad78da..c57a57742e3 100644
--- a/MantidPlot/src/MultiTabScriptInterpreter.h
+++ b/MantidPlot/src/MultiTabScriptInterpreter.h
@@ -50,7 +50,7 @@ public:
   ~MultiTabScriptInterpreter() override;
 
   /// Current interpreter
-  ScriptFileInterpreter *currentInterpreter();
+  ScriptFileInterpreter *currentInterpreter() { return m_current; };
   /// Interpreter at given index
   ScriptFileInterpreter *interpreterAt(int index);
 
diff --git a/MantidPlot/src/ProjectRecovery.cpp b/MantidPlot/src/ProjectRecovery.cpp
index da34c5e58ad..49f1b316cda 100644
--- a/MantidPlot/src/ProjectRecovery.cpp
+++ b/MantidPlot/src/ProjectRecovery.cpp
@@ -453,6 +453,8 @@ bool ProjectRecovery::loadRecoveryCheckpoint(const Poco::Path &recoveryFolder) {
     throw std::runtime_error("Could not get handle to scripting window");
   }
 
+  m_recoveryGui->connectProgressBarToRecoveryView();
+
   // Ensure the window repaints so it doesn't appear frozen before exec
   scriptWindow->executeCurrentTab(Script::ExecutionMode::Serialised);
   if (scriptWindow->getSynchronousErrorFlag()) {
diff --git a/MantidPlot/src/ProjectRecovery.h b/MantidPlot/src/ProjectRecovery.h
index 51760782b3d..a1e52db40b2 100644
--- a/MantidPlot/src/ProjectRecovery.h
+++ b/MantidPlot/src/ProjectRecovery.h
@@ -91,6 +91,7 @@ public:
   void removeLockedCheckpoints();
 
 private:
+  friend class RecoveryThread;
   /// Captures the current object in the background thread
   std::thread createBackgroundThread();
 
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryModel.cpp b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryModel.cpp
index 5d247376b35..509d8f8e368 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryModel.cpp
+++ b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryModel.cpp
@@ -16,6 +16,7 @@
 #include <Poco/Path.h>
 #include <QThread>
 #include <fstream>
+#include <QApplication>
 #include <memory>
 
 namespace {
@@ -81,7 +82,9 @@ void ProjectRecoveryModel::recoverSelectedCheckpoint(std::string &selected) {
   Mantid::API::AnalysisDataService::Instance().clear();
 
   // Recovery given the checkpoint selected here
-  selected.replace(selected.find(" "), 1, "T");
+  auto stringSpacePos = selected.find(" ");
+  if (stringSpacePos != std::string::npos)
+    selected.replace(stringSpacePos, 1, "T");
   Poco::Path checkpoint(m_projRec->getRecoveryFolderLoadPR());
   checkpoint.append(selected);
   Poco::Path output(Mantid::Kernel::ConfigService::Instance().getAppDataDir());
@@ -103,7 +106,9 @@ void ProjectRecoveryModel::openSelectedInEditor(std::string &selected) {
   Mantid::API::AnalysisDataService::Instance().clear();
 
   // Open editor for this checkpoint
-  selected.replace(selected.find(" "), 1, "T");
+  auto stringSpacePos = selected.find(" ");
+  if (stringSpacePos != std::string::npos)
+    selected.replace(stringSpacePos, 1, "T");
   auto beforeCheckpoint = m_projRec->getRecoveryFolderLoadPR();
   Poco::Path checkpoint(beforeCheckpoint);
   checkpoint.append(selected);
@@ -165,21 +170,24 @@ void ProjectRecoveryModel::updateCheckpointTried(
 bool ProjectRecoveryModel::getFailedRun() const { return m_failedRun; }
 
 void ProjectRecoveryModel::createThreadAndManage(const Poco::Path &checkpoint) {
-  std::unique_ptr<RecoveryThread> recoverThread =
-      std::make_unique<RecoveryThread>();
-  recoverThread->setProjRecPtr(m_projRec);
-  recoverThread->setCheckpoint(checkpoint);
-  recoverThread->start(QThread::HighestPriority);
-
-  // Wait for the thread to finish
-  recoverThread->wait();
+  RecoveryThread recoverThread;
+  recoverThread.setProjRecPtr(m_projRec);
+  recoverThread.setCheckpoint(checkpoint);
+  recoverThread.start(QThread::LowPriority);
+
+  while (!recoverThread.isFinished()){
+    std::this_thread::sleep_for(std::chrono::milliseconds(10));
+    QApplication::processEvents();
+  }
 
   // Set failed run member to the value from the thread
-  m_failedRun = recoverThread->getFailedRun();
+  m_failedRun = recoverThread.getFailedRun();
 }
 
 std::string ProjectRecoveryModel::decideLastCheckpoint() {
   auto mostRecentCheckpoints = m_projRec->getRecoveryFolderCheckpointsPR(
       m_projRec->getRecoveryFolderLoadPR());
-  return mostRecentCheckpoints.back().toString();
+  auto mostRecentCheckpointPath = mostRecentCheckpoints.back();
+  return mostRecentCheckpointPath.directory(mostRecentCheckpointPath.depth() -
+                                            1);
 }
\ No newline at end of file
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.cpp b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.cpp
index 0c0e1935159..fa9c24ec77b 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.cpp
+++ b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.cpp
@@ -40,6 +40,7 @@ ProjectRecoveryPresenter::~ProjectRecoveryPresenter() {
 
 bool ProjectRecoveryPresenter::startRecoveryView() {
   try {
+    m_openView = RecoveryView;
     m_recView = new ProjectRecoveryView(m_mainWindow, this);
     m_recView->exec();
   } catch (...) {
@@ -54,6 +55,7 @@ bool ProjectRecoveryPresenter::startRecoveryView() {
 
 bool ProjectRecoveryPresenter::startRecoveryFailure() {
   try {
+    m_openView = FailureView;
     m_failureView = new RecoveryFailureView(m_mainWindow, this);
     m_failureView->exec();
   } catch (...) {
@@ -135,4 +137,13 @@ void ProjectRecoveryPresenter::setUpProgressBar(
   if (secondView) {
     secondView->setProgressBarMaximum(std::stoi(row[2]));
   }
+}
+
+void ProjectRecoveryPresenter::connectProgressBarToRecoveryView(){
+  if (m_openView == RecoveryView){
+    m_recView->connectProgressBar();
+  } else {
+    m_failureView->connectProgressBar();
+  }
+  
 }
\ No newline at end of file
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.h b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.h
index 39152fec74c..b7f3091bac7 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.h
+++ b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryPresenter.h
@@ -21,6 +21,7 @@ class ProjectRecoveryView;
 class RecoveryFailureView;
 class ProjectRecoveryPresenter {
 public:
+  enum OpenView { RecoveryView, FailureView};
   // Interestingly this nullptr should never be used
   ProjectRecoveryPresenter(MantidQt::ProjectRecovery *projectRecovery,
                            ApplicationWindow *parentWindow);
@@ -36,6 +37,7 @@ public:
                                  boost::shared_ptr<QDialog> view);
   void openSelectedInEditor(QString &selected);
   void closeView();
+  void connectProgressBarToRecoveryView();
   ProjectRecoveryPresenter &operator=(const ProjectRecoveryPresenter &obj);
 
 private:
@@ -43,6 +45,7 @@ private:
                         boost::shared_ptr<QDialog> view);
   friend class ProjectRecoveryView;
   friend class RecoveryFailureView;
+  OpenView m_openView;
   ProjectRecoveryModel *m_model;
   ProjectRecoveryView *m_recView;
   RecoveryFailureView *m_failureView;
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.cpp b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.cpp
index b03b2a6cfad..775e67eabd9 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.cpp
+++ b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.cpp
@@ -5,23 +5,19 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "ProjectRecoveryView.h"
-#include "MantidKernel/UsageService.h"
 #include "ApplicationWindow.h"
-#include "ScriptingWindow.h"
-#include "ScriptFileInterpreter.h"
+#include "MantidKernel/UsageService.h"
+#include "MultiTabScriptInterpreter.h"
 #include "Script.h"
+#include "ScriptFileInterpreter.h"
+#include "ScriptingWindow.h"
 #include "ui_ProjectRecoveryWidget.h"
 #include <boost/smart_ptr/make_shared.hpp>
 
 ProjectRecoveryView::ProjectRecoveryView(QWidget *parent,
                                          ProjectRecoveryPresenter *presenter)
-    : QDialog(parent), m_progressBarCounter(0) {
-  ui = new Ui::ProjectRecoveryWidget;
-  m_presenter = presenter;      
-  connect(m_presenter->m_mainWindow->getScriptWindowHandle()
-              ->getCurrentScriptInterpreter()->getRunner().data(),
-          SIGNAL(currentLineChanged(int, bool)), this,
-          SLOT(updateProgressBar(int, bool)));
+    : QDialog(parent), ui(new Ui::ProjectRecoveryWidget),
+      m_presenter(presenter) {
   ui->setupUi(this);
   ui->tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
   ui->tableWidget->verticalHeader()->setResizeMode(QHeaderView::Stretch);
@@ -76,4 +72,11 @@ void ProjectRecoveryView::updateProgressBar(int newValue, bool err) {
 
 void ProjectRecoveryView::setProgressBarMaximum(int newValue) {
   ui->progressBar->setMaximum(newValue);
+}
+
+void ProjectRecoveryView::connectProgressBar() {
+  connect(&m_presenter->m_mainWindow->getScriptWindowHandle()
+               ->getCurrentScriptRunner(),
+          SIGNAL(currentLineChanged(int, bool)), this,
+          SLOT(updateProgressBar(int, bool)));
 }
\ No newline at end of file
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.h b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.h
index 778e684460c..8ea03a379ca 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.h
+++ b/MantidPlot/src/ProjectRecoveryGUIs/ProjectRecoveryView.h
@@ -24,6 +24,7 @@ public:
   ~ProjectRecoveryView();
   void reject() override;
   void setProgressBarMaximum(int newValue);
+  void connectProgressBar();
 
 public slots:
   void updateProgressBar(int newValue, bool err);
@@ -35,7 +36,7 @@ private slots:
 
 private:
   void addDataToTable(Ui::ProjectRecoveryWidget *ui);
-  unsigned int m_progressBarCounter;
+  
   Ui::ProjectRecoveryWidget *ui;
   ProjectRecoveryPresenter *m_presenter;
 };
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.cpp b/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.cpp
index 94734988f5d..dc10d4fadf9 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.cpp
+++ b/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.cpp
@@ -7,13 +7,14 @@
 #include "RecoveryFailureView.h"
 #include "ui_RecoveryFailure.h"
 #include "ApplicationWindow.h"
+#include "ScriptingWindow.h"
+#include "Script.h"
 #include "MantidKernel/UsageService.h"
 #include <boost/smart_ptr/make_shared.hpp>
 
 RecoveryFailureView::RecoveryFailureView(QWidget *parent,
                                          ProjectRecoveryPresenter *presenter)
-    : QDialog(parent), ui(new Ui::RecoveryFailure), m_presenter(presenter),
-      m_progressBarCounter(0) {
+    : QDialog(parent), ui(new Ui::RecoveryFailure), m_presenter(presenter){
   ui->setupUi(this);
   ui->tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
   ui->tableWidget->verticalHeader()->setResizeMode(QHeaderView::Stretch);
@@ -100,10 +101,19 @@ void RecoveryFailureView::reject() {
       "Feature", "ProjectRecoveryFailureWindow->StartMantidNormally", false);
 }
 
-void RecoveryFailureView::updateProgressBar(int newValue) {
-  ui->progressBar->setValue(newValue);
+void RecoveryFailureView::updateProgressBar(int newValue, bool err) {
+  if (!err) {
+    ui->progressBar->setValue(newValue);
+  }
 }
 
 void RecoveryFailureView::setProgressBarMaximum(int newValue) {
   ui->progressBar->setMaximum(newValue);
+}
+
+void RecoveryFailureView::connectProgressBar() {
+  connect(&m_presenter->m_mainWindow->getScriptWindowHandle()
+              ->getCurrentScriptRunner(),
+          SIGNAL(currentLineChanged(int, bool)), this,
+          SLOT(updateProgressBar(int, bool)));
 }
\ No newline at end of file
diff --git a/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.h b/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.h
index efe59f01d50..4364d602a29 100644
--- a/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.h
+++ b/MantidPlot/src/ProjectRecoveryGUIs/RecoveryFailureView.h
@@ -23,8 +23,11 @@ public:
                                ProjectRecoveryPresenter *presenter = nullptr);
   ~RecoveryFailureView();
   void reject() override;
-  void updateProgressBar(int newValue);
+
   void setProgressBarMaximum(int newValue);
+  void connectProgressBar();
+public slots:
+  void updateProgressBar(int newValue, bool err);
 
 private slots:
   void onClickLastCheckpoint();
@@ -35,7 +38,6 @@ private slots:
 private:
   void addDataToTable(Ui::RecoveryFailure *ui);
 
-  unsigned int m_progressBarCounter;
   Ui::RecoveryFailure *ui;
   ProjectRecoveryPresenter *m_presenter;
 };
diff --git a/MantidPlot/src/ScriptFileInterpreter.h b/MantidPlot/src/ScriptFileInterpreter.h
index 03a5ad6a138..60a97f5667f 100644
--- a/MantidPlot/src/ScriptFileInterpreter.h
+++ b/MantidPlot/src/ScriptFileInterpreter.h
@@ -57,7 +57,7 @@ public:
   /// Is the script running
   virtual bool isExecuting() const;
 
-  QSharedPointer<Script> getRunner() { return m_runner; }
+  const Script &getRunner() const{ return *m_runner.data(); }
 
 public slots:
   /// Save to the currently stored name
diff --git a/MantidPlot/src/ScriptingWindow.cpp b/MantidPlot/src/ScriptingWindow.cpp
index 7cfd0e0d5b7..10440154497 100644
--- a/MantidPlot/src/ScriptingWindow.cpp
+++ b/MantidPlot/src/ScriptingWindow.cpp
@@ -906,6 +906,6 @@ Script::ExecutionMode ScriptingWindow::getExecutionMode() const {
     return Script::Serialised;
 }
 
-ScriptFileInterpreter *ScriptingWindow::getCurrentScriptInterpreter() {
-  return m_manager->m_current;
+const Script& ScriptingWindow::getCurrentScriptRunner() {
+  return m_manager->currentInterpreter()->getRunner();
 }
\ No newline at end of file
diff --git a/MantidPlot/src/ScriptingWindow.h b/MantidPlot/src/ScriptingWindow.h
index fd5cb2f9945..16314cbbf77 100644
--- a/MantidPlot/src/ScriptingWindow.h
+++ b/MantidPlot/src/ScriptingWindow.h
@@ -77,7 +77,7 @@ public:
   // We set a flag on failure to avoid problems with Async not returning success
   bool getSynchronousErrorFlag() { return m_failureFlag; }
 
-  ScriptFileInterpreter *getCurrentScriptInterpreter();
+  const Script &getCurrentScriptRunner();
 
 signals:
   /// Show the scripting language dialog
-- 
GitLab