diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py index 8afc6d1b6af9499691bba176ff693985619ff779..b8b8353768d945544ae3f82fb9b7b954b4a6dc9b 100644 --- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py +++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py @@ -48,3 +48,6 @@ class MatrixWorkspaceDisplayModel(object): return (MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.x), MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.y), MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.e)) + + def workspace_equals(self, workspace_name): + return workspace_name == self._ws.name() diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py index e01fb1768b4761af792617dc9daa73c9b438ffd5..1255672150459b1308c9030f7ac5f2a8732b6963 100644 --- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py +++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py @@ -12,6 +12,7 @@ from __future__ import absolute_import, division, print_function from mantid.plots.utility import MantidAxType from mantidqt.widgets.common.table_copying import copy_bin_values, copy_cells, copy_spectrum_values, \ show_no_selection_to_copy_toast +from mantidqt.widgets.common.workspacedisplay_ads_observer import WorkspaceDisplayADSObserver from mantidqt.widgets.matrixworkspacedisplay.table_view_model import MatrixWorkspaceTableViewModelType from .model import MatrixWorkspaceDisplayModel from .view import MatrixWorkspaceDisplayView @@ -23,7 +24,7 @@ class MatrixWorkspaceDisplay(object): A_LOT_OF_THINGS_TO_PLOT_MESSAGE = "You selected {} spectra to plot. Are you sure you want to plot that many?" NUM_SELECTED_FOR_CONFIRMATION = 10 - def __init__(self, ws, plot=None, parent=None, model=None, view=None): + def __init__(self, ws, plot=None, parent=None, model=None, view=None, ads_observer=None): """ Creates a display for the provided workspace. @@ -40,12 +41,34 @@ class MatrixWorkspaceDisplay(object): self.model.get_name()) self.plot = plot + + if ads_observer: + self.ads_observer = ads_observer + else: + self.ads_observer = WorkspaceDisplayADSObserver(self) + self.setup_tables() self.view.set_context_menu_actions(self.view.table_y) self.view.set_context_menu_actions(self.view.table_x) self.view.set_context_menu_actions(self.view.table_e) + def close(self, workspace_name): + if self.model.workspace_equals(workspace_name): + # if the observer is not cleared here then the C++ object is never freed, + # and observers keep getting created, and triggering on ADS events + self.ads_observer = None + self.view.close_later() + + def force_close(self): + self.ads_observer = None + self.view.close_later() + + def replace_workspace(self, workspace_name, workspace): + if self.model.workspace_equals(workspace_name): + self.model = MatrixWorkspaceDisplayModel(workspace) + self.view.get_active_tab().viewport().update() + @classmethod def supports(cls, ws): """ diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py index 6ba1c5562f48065881c563e99e3867e2df945233..86f12afd0d79cd9c8997bb207168c4f43293746a 100644 --- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py +++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py @@ -12,7 +12,7 @@ from __future__ import (absolute_import, division, print_function) from functools import partial from qtpy import QtGui -from qtpy.QtCore import Qt +from qtpy.QtCore import Qt, Signal, Slot from qtpy.QtGui import QKeySequence from qtpy.QtWidgets import (QAbstractItemView, QAction, QHeaderView, QMessageBox, QTabWidget, QTableView) @@ -28,7 +28,9 @@ class MatrixWorkspaceTableView(QTableView): header = self.horizontalHeader() header.sectionDoubleClicked.connect(self.handle_double_click) - def resizeEvent(self, _): + def resizeEvent(self, event): + super(MatrixWorkspaceTableView, self).resizeEvent(event) + header = self.horizontalHeader() header.setSectionResizeMode(QHeaderView.Interactive) @@ -38,6 +40,8 @@ class MatrixWorkspaceTableView(QTableView): class MatrixWorkspaceDisplayView(QTabWidget): + close_signal = Signal() + def __init__(self, presenter, parent=None, name=''): super(MatrixWorkspaceDisplayView, self).__init__(parent) @@ -64,9 +68,27 @@ class MatrixWorkspaceDisplayView(QTabWidget): self.table_x = self.add_table("X values") self.table_e = self.add_table("E values") + self.close_signal.connect(self._run_close) + self.resize(600, 400) self.show() + def close_later(self): + """ + Emits a close signal to the main GUI thread that triggers the built-in close method. + + This function can be called from outside the main GUI thread. It is currently + used to close the window when the relevant workspace is deleted. + + When the signal is emitted, the execution returns to the GUI thread, and thus + GUI code can be executed. + """ + self.close_signal.emit() + + @Slot() + def _run_close(self): + self.close() + def add_table(self, label): tab = MatrixWorkspaceTableView(self) @@ -79,6 +101,9 @@ class MatrixWorkspaceDisplayView(QTabWidget): self.presenter.action_keypress_copy(self.tabs[self.currentIndex()]) super(MatrixWorkspaceDisplayView, self).keyPressEvent(event) + def get_active_tab(self): + return self.tabs[self.active_tab_index] + def set_scroll_position_on_new_focused_tab(self, new_tab_index): """ Updates the new focused tab's scroll position to match the old one.