From 8565f4a8ed9ed5ad33aaf60fdeba90c8c37058b6 Mon Sep 17 00:00:00 2001
From: Conor Finn <conor.finn@stfc.ac.uk>
Date: Wed, 23 Oct 2019 15:37:45 +0100
Subject: [PATCH] RE #27012 Fix debug error on windows

Debug error appeared on windows when buttons are enabled at the end of
the calibration and focus.

By emitting a signal instead of calling the function to enable the
buttons directly, windows stops complaining about threads interacting
with the GUI.
---
 .../tabs/calibration/presenter.py             | 19 +++++++++---------
 .../calibration/test/test_calib_presenter.py  | 12 +++++------
 .../tabs/calibration/view.py                  |  7 ++++++-
 .../tabs/focus/presenter.py                   | 20 +++++++++----------
 .../tabs/focus/test/test_focus_presenter.py   | 10 +++++-----
 .../tabs/focus/view.py                        |  7 ++++++-
 6 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/presenter.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/presenter.py
index 79c5f9e5008..d18860464a3 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/presenter.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/presenter.py
@@ -24,6 +24,7 @@ class CalibrationPresenter(object):
 
         # Connect view signals to local functions.
         self.view.set_on_calibrate_clicked(self.on_calibrate_clicked)
+        self.view.set_enable_controls_connection(self.set_calibrate_controls_enabled)
 
         # Main Window State Variables
         self.instrument = "ENGINX"
@@ -54,11 +55,10 @@ class CalibrationPresenter(object):
             "rb_num": rb_num
         },
                                 error_cb=self._on_error,
-                                finished_cb=self.enable_calibrate_buttons,
                                 success_cb=self.set_current_calibration)
         self.pending_calibration["vanadium_path"] = vanadium_path
         self.pending_calibration["ceria_path"] = calib_path
-        self.disable_calibrate_buttons()
+        self.set_calibrate_controls_enabled(False)
         self.worker.start()
 
     def set_current_calibration(self, success_info):
@@ -66,7 +66,7 @@ class CalibrationPresenter(object):
         self.current_calibration = self.pending_calibration
         self.calibration_notifier.notify_subscribers(self.current_calibration)
         self.pending_calibration = {"vanadium_path": None, "ceria_path": None}
-        self.enable_calibrate_buttons()
+        self.emit_enable_button_signal()
 
     def set_instrument_override(self, instrument):
         if instrument == 0:
@@ -87,17 +87,16 @@ class CalibrationPresenter(object):
         else:
             return False
 
-    def disable_calibrate_buttons(self):
-        self.view.set_calibrate_button_enabled(False)
-        self.view.set_check_plot_output_enabled(False)
+    def emit_enable_button_signal(self):
+        self.view.sig_enable_controls.emit(True)
 
-    def enable_calibrate_buttons(self):
-        self.view.set_calibrate_button_enabled(True)
-        self.view.set_check_plot_output_enabled(True)
+    def set_calibrate_controls_enabled(self, enabled):
+        self.view.set_calibrate_button_enabled(enabled)
+        self.view.set_check_plot_output_enabled(enabled)
 
     def _on_error(self, failure_info):
         logger.warning(str(failure_info))
-        self.enable_calibrate_buttons()
+        self.emit_enable_button_signal()
 
     # -----------------------
     # Observers / Observables
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_presenter.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_presenter.py
index dfb6a525ac9..553a0190b18 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_presenter.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_presenter.py
@@ -55,31 +55,31 @@ class CalibrationPresenterTest(unittest.TestCase):
         worker_method.assert_not_called()
 
     def test_controls_disabled_disables_both(self):
-        self.presenter.disable_calibrate_buttons()
+        self.presenter.set_calibrate_controls_enabled(False)
 
         self.view.set_calibrate_button_enabled.assert_called_with(False)
         self.view.set_check_plot_output_enabled.assert_called_with(False)
 
     def test_controls_enabled_enables_both(self):
-        self.presenter.disable_calibrate_buttons()
+        self.presenter.set_calibrate_controls_enabled(False)
 
         self.view.set_calibrate_button_enabled.assert_called_with(False)
         self.view.set_check_plot_output_enabled.assert_called_with(False)
 
-        self.presenter.enable_calibrate_buttons()
+        self.presenter.set_calibrate_controls_enabled(True)
 
         self.view.set_calibrate_button_enabled.assert_called_with(True)
         self.view.set_check_plot_output_enabled.assert_called_with(True)
 
+    @patch(tab_path + ".presenter.CalibrationPresenter.emit_enable_button_signal")
     @patch(tab_path + ".presenter.logger.warning")
-    def test_on_error_posts_to_logger_and_enables_controls(self, logger):
+    def test_on_error_posts_to_logger_and_enables_controls(self, logger, emit):
         fail_info = 2024278
 
         self.presenter._on_error(fail_info)
 
         logger.assert_called_with(str(fail_info))
-        self.view.set_calibrate_button_enabled.assert_called_with(True)
-        self.view.set_check_plot_output_enabled.assert_called_with(True)
+        self.assertEqual(emit.call_count, 1)
 
     def test_validation_of_run_numbers(self):
         self.view.get_calib_valid.return_value = False
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/view.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/view.py
index 5076e2913b0..d4de22c4d07 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/view.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/view.py
@@ -6,7 +6,7 @@
 # SPDX - License - Identifier: GPL - 3.0 +
 
 from __future__ import (absolute_import, division, print_function)
-from qtpy import QtWidgets
+from qtpy import QtWidgets, QtCore
 
 from mantidqt.utils.qt import load_ui
 
@@ -14,6 +14,8 @@ Ui_calib, _ = load_ui(__file__, "calibration_tab.ui")
 
 
 class CalibrationView(QtWidgets.QWidget, Ui_calib):
+    sig_enable_controls = QtCore.Signal(bool)
+
     def __init__(self, parent=None, instrument="ENGINX"):
         super(CalibrationView, self).__init__(parent)
         self.setupUi(self)
@@ -35,6 +37,9 @@ class CalibrationView(QtWidgets.QWidget, Ui_calib):
     def set_on_calibrate_clicked(self, slot):
         self.button_calibrate.clicked.connect(slot)
 
+    def set_enable_controls_connection(self, slot):
+        self.sig_enable_controls.connect(slot)
+
     def set_calibrate_button_enabled(self, enabled):
         self.button_calibrate.setEnabled(enabled)
 
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/presenter.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/presenter.py
index eef9a62faee..ac9f24bd4b7 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/presenter.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/presenter.py
@@ -23,6 +23,7 @@ class FocusPresenter(object):
 
         # Connect view signals to local methods.
         self.view.set_on_focus_clicked(self.on_focus_clicked)
+        self.view.set_enable_controls_connection(self.set_focus_controls_enabled)
 
         # Variables from other GUI tabs.
         self.current_calibration = {"vanadium_path": None, "ceria_path": None}
@@ -48,8 +49,8 @@ class FocusPresenter(object):
             self.model.focus_run,
             (focus_path, banks, plot_output, self.instrument, rb_num, self.current_calibration),
             error_cb=self._on_worker_error,
-            finished_cb=self._enable_focus_controls)
-        self._disable_focus_controls()
+            finished_cb=self.emit_enable_button_signal)
+        self.set_focus_controls_enabled(False)
         self.worker.start()
 
     def set_instrument_override(self, instrument):
@@ -89,15 +90,11 @@ class FocusPresenter(object):
 
     def _on_worker_error(self, failure_info):
         logger.warning(str(failure_info))
-        self._enable_focus_controls()
+        self.emit_enable_button_signal()
 
-    def _enable_focus_controls(self):
-        self.view.set_focus_button_enabled(True)
-        self.view.set_plot_output_enabled(True)
-
-    def _disable_focus_controls(self):
-        self.view.set_focus_button_enabled(False)
-        self.view.set_plot_output_enabled(False)
+    def set_focus_controls_enabled(self, enabled):
+        self.view.set_focus_button_enabled(enabled)
+        self.view.set_plot_output_enabled(enabled)
 
     def _get_banks(self):
         banks = []
@@ -107,6 +104,9 @@ class FocusPresenter(object):
             banks.append("South")
         return banks
 
+    def emit_enable_button_signal(self):
+        self.view.sig_enable_controls.emit(True)
+
     def update_calibration(self, calibration):
         """
         Update the current calibration following an call from a CalibrationNotifier
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_presenter.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_presenter.py
index 0ce6745477c..4d2e22fa50d 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_presenter.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_presenter.py
@@ -46,26 +46,26 @@ class FocusPresenterTest(unittest.TestCase):
         worker.assert_not_called()
 
     def test_controls_disabled_disables_both(self):
-        self.presenter._disable_focus_controls()
+        self.presenter.set_focus_controls_enabled(False)
 
         self.view.set_focus_button_enabled.assert_called_with(False)
         self.view.set_plot_output_enabled.assert_called_with(False)
 
     def test_controls_enabled_enables_both(self):
-        self.presenter._enable_focus_controls()
+        self.presenter.set_focus_controls_enabled(True)
 
         self.view.set_focus_button_enabled.assert_called_with(True)
         self.view.set_plot_output_enabled.assert_called_with(True)
 
+    @patch(tab_path + ".presenter.FocusPresenter.emit_enable_button_signal")
     @patch(tab_path + ".presenter.logger.warning")
-    def test_on_worker_error_posts_to_logger_and_enables_controls(self, logger):
+    def test_on_worker_error_posts_to_logger_and_enables_controls(self, logger, emit):
         fail_info = 2024278
 
         self.presenter._on_worker_error(fail_info)
 
         logger.assert_called_with(str(fail_info))
-        self.view.set_focus_button_enabled.assert_called_with(True)
-        self.view.set_plot_output_enabled.assert_called_with(True)
+        self.assertEqual(emit.call_count, 1)
 
     def test_get_banks(self):
         self.view.get_north_bank.return_value = True
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/view.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/view.py
index 9ae466c15cc..4cb38f864b4 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/view.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/view.py
@@ -6,7 +6,7 @@
 # SPDX - License - Identifier: GPL - 3.0 +
 
 from __future__ import (absolute_import, division, print_function)
-from qtpy import QtWidgets
+from qtpy import QtWidgets, QtCore
 
 from mantidqt.utils.qt import load_ui
 
@@ -14,6 +14,8 @@ Ui_focus, _ = load_ui(__file__, "focus_tab.ui")
 
 
 class FocusView(QtWidgets.QWidget, Ui_focus):
+    sig_enable_controls = QtCore.Signal(bool)
+
     def __init__(self, parent=None, instrument="ENGINX"):
         super(FocusView, self).__init__(parent)
         self.setupUi(self)
@@ -24,6 +26,9 @@ class FocusView(QtWidgets.QWidget, Ui_focus):
     def set_on_focus_clicked(self, slot):
         self.button_focus.clicked.connect(slot)
 
+    def set_enable_controls_connection(self, slot):
+        self.sig_enable_controls.connect(slot)
+
     def set_instrument_override(self, instrument):
         self.finder_focus.setInstrumentOverride(instrument)
 
-- 
GitLab