From 9c435970617642fa224f15a0beea9a6aaaf1cb77 Mon Sep 17 00:00:00 2001 From: Chris Meyer <34664+cmeyer@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:55:55 -0700 Subject: [PATCH] Fix #1159. Relax undo check to ignore changes outside display item (computations) after adding graphics. --- nion/swift/DisplayPanel.py | 29 ++++----------------- nion/swift/test/DisplayPanel_test.py | 38 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/nion/swift/DisplayPanel.py b/nion/swift/DisplayPanel.py index a0af973a0..6534aa6b0 100644 --- a/nion/swift/DisplayPanel.py +++ b/nion/swift/DisplayPanel.py @@ -1161,10 +1161,6 @@ def __init__(self, document_controller: DocumentController.DocumentController, self.__document_controller = document_controller self.__display_item_proxy = display_item.create_proxy() self.__graphics = graphics # only used for perform - workspace_controller = self.__document_controller.workspace_controller - assert workspace_controller - self.__old_workspace_layout: typing.Optional[Persistence.PersistentDictType] = workspace_controller.deconstruct() - self.__new_workspace_layout: typing.Optional[Persistence.PersistentDictType] = None self.__graphics_properties = None self.__graphic_proxies = [graphic.create_proxy() for graphic in existing_graphics or list()] self.__undelete_logs: typing.List[Changes.UndeleteLog] = list() @@ -1173,8 +1169,6 @@ def __init__(self, document_controller: DocumentController.DocumentController, def close(self) -> None: self.__graphics_properties = None self.__document_controller = typing.cast(typing.Any, None) - self.__old_workspace_layout = None - self.__new_workspace_layout = None for undelete_log in self.__undelete_logs: undelete_log.close() self.__undelete_logs = typing.cast(typing.Any, None) @@ -1198,39 +1192,26 @@ def perform(self) -> None: def _get_modified_state(self) -> typing.Any: display_item = self.__display_item_proxy.item display_item_modified_state = display_item.modified_state if display_item else None - workspace_controller = self.__document_controller.workspace_controller - document_model_modified_state = workspace_controller.document_model.modified_state if workspace_controller else None - return display_item_modified_state, document_model_modified_state + return display_item_modified_state def _set_modified_state(self, modified_state: typing.Any) -> None: display_item = self.__display_item_proxy.item if display_item: - display_item.modified_state = modified_state[0] - workspace_controller = self.__document_controller.workspace_controller - if workspace_controller: - workspace_controller.document_model.modified_state = modified_state[1] + display_item.modified_state = modified_state def _redo(self) -> None: for undelete_log in reversed(self.__undelete_logs): self.__document_controller.document_model.undelete_all(undelete_log) undelete_log.close() self.__undelete_logs.clear() - workspace_controller = self.__document_controller.workspace_controller - if workspace_controller and self.__new_workspace_layout is not None: - workspace_controller.reconstruct(self.__new_workspace_layout) def _undo(self) -> None: display_item = self.__display_item_proxy.item if display_item: graphics = [graphic_proxy.item for graphic_proxy in self.__graphic_proxies] - workspace_controller = self.__document_controller.workspace_controller - if workspace_controller: - self.__new_workspace_layout = workspace_controller.deconstruct() - for graphic in graphics: - if graphic: - self.__undelete_logs.append(display_item.remove_graphic(graphic, safe=True)) - if self.__old_workspace_layout is not None: - workspace_controller.reconstruct(self.__old_workspace_layout) + for graphic in graphics: + if graphic: + self.__undelete_logs.append(display_item.remove_graphic(graphic, safe=True)) class AppendDisplayDataChannelCommand(Undo.UndoableCommand): diff --git a/nion/swift/test/DisplayPanel_test.py b/nion/swift/test/DisplayPanel_test.py index e91fa226b..758fabb42 100644 --- a/nion/swift/test/DisplayPanel_test.py +++ b/nion/swift/test/DisplayPanel_test.py @@ -3220,6 +3220,44 @@ def test_adding_fourier_filter_is_undoable_via_menu_items(self): # undo document_controller.perform_action("window.redo") self.assertEqual(1, len(display_item.graphics)) + # clean up by clearing out the periodic queue + document_controller.periodic() + + def test_adding_fourier_filter_to_data_item_with_computation_is_undoable_via_menu_items(self): + with TestContext.create_memory_context() as test_context: + # set up the layout + document_controller = test_context.create_document_controller() + document_model = document_controller.document_model + # add data item + data_item = DataItem.DataItem(numpy.zeros((10, 10))) + document_model.append_data_item(data_item) + display_item = document_model.get_display_item_for_data_item(data_item) + # add computation + document_model.get_fft_new(display_item, display_item.data_item) + # put data item in display panel + display_panel = document_controller.selected_display_panel + display_panel.set_display_panel_display_item(display_item) + display_panel.root_container.layout_immediate(Geometry.IntSize(1000 + display_panel.header_canvas_item.header_height, 1000)) + document_controller.periodic() + # focus click + display_panel.root_container.canvas_widget.simulate_mouse_click(500, 500, CanvasItem.KeyboardModifiers()) + # recompute initial + document_controller.periodic() + document_controller.document_model.recompute_all() + # add fourier graphic + document_controller.perform_action("graphics.add_spot_graphic") + self.assertEqual(1, len(display_item.graphics)) + # recompute after filter + document_controller.periodic() + document_controller.document_model.recompute_all() + # undo + document_controller.perform_action("window.undo") + self.assertEqual(0, len(display_item.graphics)) + # undo + document_controller.perform_action("window.redo") + self.assertEqual(1, len(display_item.graphics)) + # clean up by clearing out the periodic queue + document_controller.periodic() if __name__ == '__main__':