Skip to content
Snippets Groups Projects
Commit b0dcc84c authored by Conor Finn's avatar Conor Finn
Browse files

RE #27779 Implement observer between tab widgets

Observer pattern uses has the data widget as an observable that sends
the plotting widget the workspaces to add or remove from the plot when
the 3rd column in the table is ticked and unticked respectively. The
pattern also handles the removal of indiviual workspaces or the
clearing of all tracked workspaces.
parent 5615ba42
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@
from Engineering.gui.engineering_diffraction.tabs.common import create_error_message
from mantid.simpleapi import logger
from mantidqt.utils.asynchronous import AsyncTask
from mantidqt.utils.observer_pattern import GenericObservable
class FittingDataPresenter(object):
......@@ -23,6 +24,12 @@ class FittingDataPresenter(object):
self.view.set_enable_button_connection(self._enable_load_button)
self.view.set_on_remove_selected_clicked(self._remove_selected_tracked_workspaces)
self.view.set_on_remove_all_clicked(self._remove_all_tracked_workspaces)
self.view.set_on_table_cell_changed(self._handle_table_cell_changed)
# Observable Setup
self.plot_added_notifier = GenericObservable()
self.plot_removed_notifier = GenericObservable()
self.all_plots_removed_notifier = GenericObservable()
def on_load_clicked(self):
if self._validate():
......@@ -31,7 +38,8 @@ class FittingDataPresenter(object):
def remove_workspace(self, ws_name):
if ws_name in self.get_loaded_workspaces():
self.get_loaded_workspaces().pop(ws_name)
removed = self.get_loaded_workspaces().pop(ws_name)
self.plot_removed_notifier.notify_subscribers(removed)
self._repopulate_table()
def rename_workspace(self, old_name, new_name):
......@@ -42,6 +50,7 @@ class FittingDataPresenter(object):
def clear_workspaces(self):
self.get_loaded_workspaces().clear()
self.all_plots_removed_notifier.notify_subscribers()
self.row_numbers.clear()
self._repopulate_table()
......@@ -89,13 +98,22 @@ class FittingDataPresenter(object):
row_numbers = self._remove_selected_table_rows()
for row_no in row_numbers:
ws_name = self.row_numbers.pop(row_no)
self.get_loaded_workspaces().pop(ws_name)
removed = self.get_loaded_workspaces().pop(ws_name)
self.plot_removed_notifier.notify_subscribers(removed)
self._repopulate_table()
def _remove_all_tracked_workspaces(self):
self.clear_workspaces()
self._remove_all_table_rows()
def _handle_table_cell_changed(self, row, col):
if col == 2 and row in self.row_numbers: # Is from the plot check column
ws = self.model.get_loaded_workspaces()[self.row_numbers[row]]
if self.view.get_table_item(row, col).checkState() == 2: # Plot Box is checked
self.plot_added_notifier.notify_subscribers(ws)
else: # Plot box is unchecked
self.plot_removed_notifier.notify_subscribers(ws)
def _enable_load_button(self, enabled):
self.view.set_load_button_enabled(enabled)
......
......@@ -87,6 +87,9 @@ class FittingDataView(QtWidgets.QWidget, Ui_data):
def get_selected_rows(self):
return set(index.row() for index in self.table_selection.selectedIndexes())
def get_table_item(self, row, col):
return self.table_selection.item(row, col)
# =================
# State Getters
# =================
......
......@@ -111,11 +111,13 @@ class FittingDataPresenterTest(unittest.TestCase):
model_dict = {"name1": "ws1", "name2": "ws2"}
self.model.get_loaded_workspaces.return_value = model_dict
self.presenter.row_numbers = {"name1": 0, "name2": 1}
self.presenter.plot_removed_notifier = mock.MagicMock()
self.presenter.remove_workspace("name1")
self.assertEqual({"name2": "ws2"}, model_dict)
self.assertEqual({"name2": 0}, self.presenter.row_numbers)
self.assertEqual(1, self.presenter.plot_removed_notifier.notify_subscribers.call_count)
def test_remove_workspace_not_tracked(self):
model_dict = {"name1": "ws1", "name2": "ws2"}
......@@ -152,11 +154,13 @@ class FittingDataPresenterTest(unittest.TestCase):
model_dict = {"name1": "ws1", "name2": "ws2"}
self.model.get_loaded_workspaces.return_value = model_dict
self.presenter.row_numbers = {"name1": 0, "name2": 1}
self.presenter.all_plots_removed_notifier = mock.MagicMock()
self.presenter.clear_workspaces()
self.assertEqual({}, model_dict)
self.assertEqual({}, self.presenter.row_numbers)
self.assertEqual(1, self.presenter.all_plots_removed_notifier.notify_subscribers.call_count)
def test_replace_workspace_tracked(self):
model_dict = {"name1": "ws1", "name2": "ws2"}
......@@ -183,9 +187,11 @@ class FittingDataPresenterTest(unittest.TestCase):
self.presenter.row_numbers = data_presenter.TwoWayRowDict()
self.presenter.row_numbers["name1"] = 0
self.presenter.row_numbers["name2"] = 1
model_dict = {"name1": "ws1", "name2": "ws2"}
self.presenter.row_numbers["name3"] = 2
model_dict = {"name1": "ws1", "name2": "ws2", "name3": "ws3"}
self.model.get_loaded_workspaces.return_value = model_dict
self.view.remove_selected.return_value = [0]
self.view.remove_selected.return_value = [0, 2]
self.presenter.plot_removed_notifier = mock.MagicMock()
self.presenter._remove_selected_tracked_workspaces()
......@@ -194,6 +200,60 @@ class FittingDataPresenterTest(unittest.TestCase):
test_dict["name2"] = 0
self.assertEqual(self.presenter.row_numbers, test_dict)
self.assertEqual(model_dict, {"name2": "ws2"})
self.assertEqual(2, self.presenter.plot_removed_notifier.notify_subscribers.call_count)
def test_handle_table_cell_changed_checkbox_ticked(self):
mocked_table_item = mock.MagicMock()
mocked_table_item.checkState.return_value = 2
self.view.get_table_item.return_value = mocked_table_item
self.presenter.row_numbers = data_presenter.TwoWayRowDict()
self.presenter.row_numbers["name1"] = 0
self.presenter.row_numbers["name2"] = 1
model_dict = {"name1": "ws1", "name2": "ws2"}
self.model.get_loaded_workspaces.return_value = model_dict
self.presenter.plot_added_notifier = mock.MagicMock()
self.presenter.plot_removed_notifier = mock.MagicMock()
self.presenter._handle_table_cell_changed(0, 2)
self.assertEqual(1, self.presenter.plot_added_notifier.notify_subscribers.call_count)
self.presenter.plot_added_notifier.notify_subscribers.assert_any_call("ws1")
self.assertEqual(0, self.presenter.plot_removed_notifier.notify_subscribers.call_count)
def test_handle_table_cell_changed_checkbox_unticked(self):
mocked_table_item = mock.MagicMock()
mocked_table_item.checkState.return_value = 0
self.view.get_table_item.return_value = mocked_table_item
self.presenter.row_numbers = data_presenter.TwoWayRowDict()
self.presenter.row_numbers["name1"] = 0
self.presenter.row_numbers["name2"] = 1
model_dict = {"name1": "ws1", "name2": "ws2"}
self.model.get_loaded_workspaces.return_value = model_dict
self.presenter.plot_added_notifier = mock.MagicMock()
self.presenter.plot_removed_notifier = mock.MagicMock()
self.presenter._handle_table_cell_changed(0, 2)
self.assertEqual(0, self.presenter.plot_added_notifier.notify_subscribers.call_count)
self.assertEqual(1, self.presenter.plot_removed_notifier.notify_subscribers.call_count)
self.presenter.plot_removed_notifier.notify_subscribers.assert_any_call("ws1")
def test_handle_table_cell_changed_other_element(self):
mocked_table_item = mock.MagicMock()
mocked_table_item.checkState.return_value = 2
self.view.get_table_item.return_value = mocked_table_item
self.presenter.row_numbers = data_presenter.TwoWayRowDict()
self.presenter.row_numbers["name1"] = 0
self.presenter.row_numbers["name2"] = 1
model_dict = {"name1": "ws1", "name2": "ws2"}
self.model.get_loaded_workspaces.return_value = model_dict
self.presenter.plot_added_notifier = mock.MagicMock()
self.presenter.plot_removed_notifier = mock.MagicMock()
self.presenter._handle_table_cell_changed(1, 1)
self.assertEqual(0, self.presenter.plot_added_notifier.notify_subscribers.call_count)
self.assertEqual(0, self.presenter.plot_removed_notifier.notify_subscribers.call_count)
if __name__ == '__main__':
......
......@@ -15,3 +15,10 @@ class FittingPresenter(object):
self.data_widget = FittingDataWidget(self.view, view=self.view.get_data_widget())
self.plot_widget = FittingPlotWidget(self.view, view=self.view.get_plot_widget())
self.data_widget.presenter.plot_removed_notifier.add_subscriber(
self.plot_widget.workspace_removed_observer)
self.data_widget.presenter.plot_added_notifier.add_subscriber(
self.plot_widget.workspace_added_observer)
self.data_widget.presenter.all_plots_removed_notifier.add_subscriber(
self.plot_widget.all_workspaces_removed_observer)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment