From 93b8647b6b362551116d8d6ef64fdd3dd116b4f6 Mon Sep 17 00:00:00 2001 From: JackEAllen Date: Thu, 7 Nov 2024 09:50:43 +0000 Subject: [PATCH 1/6] Add stop reconstruction button (cherry picked from commit b5a538f5521babb11d0e48a9e52905bbf608991b) --- mantidimaging/gui/dialogs/async_task/view.py | 8 ++++++++ mantidimaging/gui/ui/async_task_dialog.ui | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/mantidimaging/gui/dialogs/async_task/view.py b/mantidimaging/gui/dialogs/async_task/view.py index d3277246114..7b8a0c67e12 100644 --- a/mantidimaging/gui/dialogs/async_task/view.py +++ b/mantidimaging/gui/dialogs/async_task/view.py @@ -25,6 +25,8 @@ def __init__(self, parent: QMainWindow): self.progressBar.setMaximum(1000) self.show_timer = QTimer(self) + self.cancelButton.clicked.connect(self.presenter.stop_progress) + self.cancelButton.hide() self.hide() @property @@ -70,6 +72,12 @@ def show_from_timer(self) -> None: if self._presenter is not None and self.presenter.task_is_running: self.show() + def show_cancel_button(self, cancelable: bool) -> None: + if cancelable: + self.cancelButton.show() + else: + self.cancelButton.hide() + def start_async_task_view(parent: QMainWindow, task: Callable, diff --git a/mantidimaging/gui/ui/async_task_dialog.ui b/mantidimaging/gui/ui/async_task_dialog.ui index 6682fda083d..2713ee7bd9c 100644 --- a/mantidimaging/gui/ui/async_task_dialog.ui +++ b/mantidimaging/gui/ui/async_task_dialog.ui @@ -39,6 +39,13 @@ false + + + + Cancel + + + From 0f4f3b5aca3bdccc2ddf4c178dadb436e644fd58 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Thu, 7 Nov 2024 10:42:36 +0000 Subject: [PATCH 2/6] Hook up stop button to cancel progress (cherry picked from commit eb225aaea60058d29f5a17a7667697ac50026d01) --- mantidimaging/gui/dialogs/async_task/presenter.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mantidimaging/gui/dialogs/async_task/presenter.py b/mantidimaging/gui/dialogs/async_task/presenter.py index c00fa56be64..fbf4c856fd2 100644 --- a/mantidimaging/gui/dialogs/async_task/presenter.py +++ b/mantidimaging/gui/dialogs/async_task/presenter.py @@ -65,3 +65,9 @@ def task_is_running(self) -> None: def progress_update(self) -> None: msg = self.progress.last_status_message() self.progress_updated.emit(self.progress.completion(), msg if msg is not None else '') + + def show_stop_button(self, show: bool = False) -> None: + self.view.show_cancel_button(show) + + def stop_progress(self): + self.progress.cancel("Cancelled by user") From ad7641005c0eb19e8c520d019556853b1423f412 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Thu, 7 Nov 2024 10:40:42 +0000 Subject: [PATCH 3/6] When cancelling a progress use StopIteration (cherry picked from commit 9ba1eeb17a3abf2dfc71bca05cbf82b81742f235) --- mantidimaging/core/utility/progress_reporting/progress.py | 2 +- .../core/utility/progress_reporting/test/progress_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mantidimaging/core/utility/progress_reporting/progress.py b/mantidimaging/core/utility/progress_reporting/progress.py index b45009b2247..36077d47db4 100644 --- a/mantidimaging/core/utility/progress_reporting/progress.py +++ b/mantidimaging/core/utility/progress_reporting/progress.py @@ -197,7 +197,7 @@ def update(self, steps: int = 1, msg: str = "", force_continue: bool = False) -> # Force cancellation on progress update if self.should_cancel and not force_continue: - raise RuntimeError('Task has been cancelled') + raise StopIteration('Task has been cancelled') @staticmethod def calculate_mean_time(progress_history: list[ProgressHistory]) -> float: diff --git a/mantidimaging/core/utility/progress_reporting/test/progress_test.py b/mantidimaging/core/utility/progress_reporting/test/progress_test.py index d2b0f08ecd3..ea5bdbc6a7c 100644 --- a/mantidimaging/core/utility/progress_reporting/test/progress_test.py +++ b/mantidimaging/core/utility/progress_reporting/test/progress_test.py @@ -241,7 +241,7 @@ def test_cancellation(self): self.assertTrue(p.should_cancel) else: - with self.assertRaises(RuntimeError): + with self.assertRaises(StopIteration): p.update() self.assertFalse(p.is_completed()) From f5f9beb410a59c7979d0507d6ab7fd25f242e91b Mon Sep 17 00:00:00 2001 From: JackEAllen Date: Tue, 12 Nov 2024 08:37:57 +0000 Subject: [PATCH 4/6] Add Cancelable as Argument to start_async_task_view() --- mantidimaging/gui/dialogs/async_task/view.py | 4 +++- mantidimaging/gui/windows/recon/test/presenter_test.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mantidimaging/gui/dialogs/async_task/view.py b/mantidimaging/gui/dialogs/async_task/view.py index 7b8a0c67e12..1f0cb0e0044 100644 --- a/mantidimaging/gui/dialogs/async_task/view.py +++ b/mantidimaging/gui/dialogs/async_task/view.py @@ -84,7 +84,8 @@ def start_async_task_view(parent: QMainWindow, on_complete: Callable, kwargs: dict | None = None, tracker: set[Any] | None = None, - busy: bool | None = False): + busy: bool | None = False, + cancelable: bool = False) -> None: atd = AsyncTaskDialogView(parent) if not kwargs: kwargs = {'progress': Progress()} @@ -96,6 +97,7 @@ def start_async_task_view(parent: QMainWindow, atd.progressBar.setMinimum(0) atd.progressBar.setMaximum(0) + atd.presenter.show_stop_button(cancelable) atd.presenter.set_task(task) atd.presenter.set_on_complete(on_complete) atd.presenter.set_parameters(**kwargs) diff --git a/mantidimaging/gui/windows/recon/test/presenter_test.py b/mantidimaging/gui/windows/recon/test/presenter_test.py index e102375354b..dda32acbc84 100644 --- a/mantidimaging/gui/windows/recon/test/presenter_test.py +++ b/mantidimaging/gui/windows/recon/test/presenter_test.py @@ -217,7 +217,8 @@ def test_do_reconstruct_volume(self, mock_async_task): self.presenter.model.run_full_recon, self.presenter._on_volume_recon_done, {'recon_params': self.view.recon_params()}, - tracker=self.presenter.async_tracker) + tracker=self.presenter.async_tracker, + cancelable=True) @mock.patch('mantidimaging.gui.windows.recon.presenter.CORInspectionDialogView') def test_do_refine_selected_cor_declined(self, mock_corview): From 9a954149e6fade86a3224c2ca600f9f65ceebc2f Mon Sep 17 00:00:00 2001 From: JackEAllen Date: Tue, 12 Nov 2024 08:44:21 +0000 Subject: [PATCH 5/6] Pass cancelable as an Argument to start_async_task_view() --- mantidimaging/gui/windows/recon/presenter.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mantidimaging/gui/windows/recon/presenter.py b/mantidimaging/gui/windows/recon/presenter.py index 44804a4b83a..348cad57a44 100644 --- a/mantidimaging/gui/windows/recon/presenter.py +++ b/mantidimaging/gui/windows/recon/presenter.py @@ -225,7 +225,8 @@ def do_reconstruct_volume(self) -> None: start_async_task_view(self.view, self.model.run_full_recon, self._on_volume_recon_done, {'recon_params': self.view.recon_params()}, - tracker=self.async_tracker) + tracker=self.async_tracker, + cancelable=True) def _get_reconstruct_slice(self, cor, slice_idx: int, call_back: Callable[[TaskWorkerThread], None]) -> None: # If no COR is provided and there are regression results then calculate @@ -238,7 +239,8 @@ def _get_reconstruct_slice(self, cor, slice_idx: int, call_back: Callable[[TaskW 'cor': cor, 'recon_params': self.view.recon_params() }, - tracker=self.async_tracker) + tracker=self.async_tracker, + cancelable=True) def _get_slice_index(self, slice_idx: int | None) -> int: if slice_idx is None: From 0d4cd4c9a6709177f1153bc698e0059e80206083 Mon Sep 17 00:00:00 2001 From: JackEAllen Date: Fri, 8 Nov 2024 14:42:31 +0000 Subject: [PATCH 6/6] Release Notes --- .../next/dev-2370-cancel_async_task_progress_dialog | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/release_notes/next/dev-2370-cancel_async_task_progress_dialog diff --git a/docs/release_notes/next/dev-2370-cancel_async_task_progress_dialog b/docs/release_notes/next/dev-2370-cancel_async_task_progress_dialog new file mode 100644 index 00000000000..6c3dd998aad --- /dev/null +++ b/docs/release_notes/next/dev-2370-cancel_async_task_progress_dialog @@ -0,0 +1 @@ +#2370: Add a cancel button to AsyncTaskDialog progress window \ No newline at end of file