diff --git a/docs/source/release/v3.14.0/sans.rst b/docs/source/release/v3.14.0/sans.rst index f6ef7b0117f50ae634c1acb887d29b03f23f111d..f227880c6c414a77346bb3936cfda4558c632fee 100644 --- a/docs/source/release/v3.14.0/sans.rst +++ b/docs/source/release/v3.14.0/sans.rst @@ -22,8 +22,10 @@ Improved * Added tabbing support to table. * Added error notifications on a row by row basis. * Updated file adding to prefix the instrument name -* Updated file finding to be able to find added runs withour instrument name prefix +* Updated file finding to be able to find added runs without instrument name prefix * Updated GUI code so calculated merge scale and shift are shown after reduction. +* Automatically remembers last loaded user file +* Added display of current save directory Bug fixes ######### diff --git a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py index 0d6f1331ac2e238218a76a955fe66fbcc820eebb..a0b6b79777fe7dce37a250d380bd4c89be0f4e4e 100644 --- a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py +++ b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py @@ -35,7 +35,8 @@ from sans.common.enums import (ReductionDimensionality, OutputMode, SaveType, SA from sans.common.file_information import SANSFileInformationFactory from sans.gui_logic.gui_common import (get_reduction_mode_from_gui_selection, get_reduction_mode_strings_for_gui, get_string_for_gui_from_reduction_mode, GENERIC_SETTINGS, load_file, - get_instrument_from_gui_selection, get_string_for_gui_from_instrument) + load_default_file, set_setting, get_instrument_from_gui_selection, + get_string_for_gui_from_instrument) from sans.common.general_functions import get_instrument @@ -167,6 +168,7 @@ class SANSDataProcessorGui(QMainWindow, ui_sans_data_processor_window.Ui_SansDat # Q Settings self.__generic_settings = GENERIC_SETTINGS self.__path_key = "sans_path" + self.__user_file_key = "user_file" self.__instrument_name = "sans_instrument" self.__mask_file_input_path_key = "mask_files" @@ -483,9 +485,21 @@ class SANSDataProcessorGui(QMainWindow, ui_sans_data_processor_window.Ui_SansDat load_file(self.user_file_line_edit, "*.*", self.__generic_settings, self.__path_key, self.get_user_file_path) + # Set full user file path for default loading + set_setting(self.__generic_settings, self.__user_file_key, self.get_user_file_path()) + # Notify presenters self._call_settings_listeners(lambda listener: listener.on_user_file_load()) + def set_out_default_user_file(self): + """ + Load a default user file, called on view set-up + """ + load_default_file(self.user_file_line_edit, self.__generic_settings, self.__user_file_key) + + if self.get_user_file_path() != "": + self._call_settings_listeners(lambda listener: listener.on_user_file_load()) + def _on_batch_file_load(self): """ Load the batch file diff --git a/scripts/SANS/sans/gui_logic/gui_common.py b/scripts/SANS/sans/gui_logic/gui_common.py index 328af00c28477bd72db05352c0e5eab244b4f096..3603957bc11b4797aced669c34755da3a6a6bdfa 100644 --- a/scripts/SANS/sans/gui_logic/gui_common.py +++ b/scripts/SANS/sans/gui_logic/gui_common.py @@ -186,10 +186,23 @@ def load_file(line_edit_field, filter_for_dialog, q_settings_group_key, q_settin # Save the new location new_path, _ = os.path.split(func()) if new_path: - settings = QSettings() - settings.beginGroup(q_settings_group_key) - settings.setValue(q_settings_key, new_path) - settings.endGroup() + set_setting(q_settings_group_key, q_settings_key, new_path) + + +def load_default_file(line_edit_field, q_settings_group_key, q_settings_key): + settings = QSettings() + settings.beginGroup(q_settings_group_key) + default_file = settings.value(q_settings_key, "", type=str) + settings.endGroup() + + line_edit_field.setText(default_file) + + +def set_setting(q_settings_group_key, q_settings_key, value): + settings = QSettings() + settings.beginGroup(q_settings_group_key) + settings.setValue(q_settings_key, value) + settings.endGroup() def open_file_dialog(line_edit, filter_text, directory): diff --git a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py index 060efeaf4b8b10907bed4d659c4688e4f18638eb..b6ae9778012bcec03524ebc61a4d762b462785ee 100644 --- a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py +++ b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py @@ -237,6 +237,9 @@ class RunTabPresenter(object): self._view.setup_layout() self._view.set_out_file_directory(ConfigService.Instance().getString("defaultsave.directory")) + + self._view.set_out_default_user_file() + self._view.set_hinting_line_edit_for_column( self._table_model.column_name_converter.index('options_column_model'), self._table_model.get_options_hint_strategy()) @@ -396,6 +399,7 @@ class RunTabPresenter(object): self.on_processing_error(row, error) if not states: + self.sans_logger.warning("No states. Ending processing of batch table.") self.on_processing_finished(None) return @@ -601,6 +605,12 @@ class RunTabPresenter(object): stop_time_state_generation = time.time() time_taken = stop_time_state_generation - start_time_state_generation self.sans_logger.information("The generation of all states took {}s".format(time_taken)) + + if errors: + self.sans_logger.warning("Errors in getting states...") + for _, v in errors.item(): + self.sans_logger.warning("{}".format(v)) + return states, errors def get_state_for_row(self, row_index, file_lookup=True): diff --git a/scripts/test/SANS/gui_logic/run_tab_presenter_test.py b/scripts/test/SANS/gui_logic/run_tab_presenter_test.py index 77694bc7fef6f8f01e446c34a6b7af62880a022a..c0ca2533823eea780018be17c8c68cc6064a8546 100644 --- a/scripts/test/SANS/gui_logic/run_tab_presenter_test.py +++ b/scripts/test/SANS/gui_logic/run_tab_presenter_test.py @@ -156,6 +156,22 @@ class RunTabPresenterTest(unittest.TestCase): # clean up remove_file(user_file_path) + def test_that_checks_default_user_file(self): + # Setup presenter and mock view + view, settings_diagnostic_tab, _ = create_mock_view("") + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(view) + + self.assertEqual( + presenter._view.set_out_default_user_file.call_count, 1, + "Expected mock to have been called once. Called {} times.".format( + presenter._view.set_out_default_user_file.call_count)) + + self.assertEqual( + presenter._view._call_settings_listeners.call_count, 0, + "Expected mock to not have been called. Called {} times.".format( + presenter._view._call_settings_listeners.call_count)) + def test_fails_silently_when_user_file_does_not_exist(self): self.os_patcher.stop() view, _, _ = create_mock_view("non_existent_user_file")