From 4c627441412ff02e296ce13413bd7696d50704e1 Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Tue, 16 May 2023 14:59:29 +0200 Subject: [PATCH 01/13] "This is a short test to make sure I can actually push to remote before starting anything; updates 3446" From fbf0d3a595caa6c683a23654dc6c8d66c3d3a5fb Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Tue, 16 May 2023 15:00:56 +0200 Subject: [PATCH 02/13] "This is a short test to make sure I can actually push to remote before starting anything; updates 3446" From fd42568a93cc926380c14a5a5df56d9e015c0d5e Mon Sep 17 00:00:00 2001 From: ggoneiESS Date: Tue, 16 May 2023 15:05:30 +0200 Subject: [PATCH 03/13] "This is a short test to make sure I can actually push to remote before starting anything; updates 3446" From c442a7ffba2b46d4ded71457646b9204fbda92ce Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Fri, 9 Jun 2023 17:46:27 +0200 Subject: [PATCH 04/13] add'n of (starting?) filewriter module attribute --- nexus_constructor/add_component_window.py | 4 ++-- nexus_constructor/common_attrs.py | 1 + nexus_constructor/field_utils.py | 18 +++++++++++++--- nexus_constructor/field_widget.py | 22 ++++++++++--------- nexus_constructor/json/load_from_json.py | 3 ++- nexus_constructor/model/module.py | 26 +++++++++++++++++++++++ nexus_constructor/module_view.py | 6 +++--- nexus_constructor/ui_utils.py | 4 ++-- nexus_constructor/validators.py | 8 ++++--- requirements.txt | 4 +++- ui/main_window.py | 1 + 11 files changed, 72 insertions(+), 25 deletions(-) diff --git a/nexus_constructor/add_component_window.py b/nexus_constructor/add_component_window.py index 0484571a5..1496d8b6c 100644 --- a/nexus_constructor/add_component_window.py +++ b/nexus_constructor/add_component_window.py @@ -33,7 +33,7 @@ OFFGeometryNoNexus, ) from nexus_constructor.model.model import Model -from nexus_constructor.model.module import Dataset, Link +from nexus_constructor.model.module import Dataset, Link, FileWriter from nexus_constructor.pixel_options import PixelOptions from nexus_constructor.ui_utils import ( file_dialog, @@ -763,7 +763,7 @@ def add_fields_to_component( for i in range(fields_widget.count()): widget = fields_widget.itemWidget(fields_widget.item(i)) try: - if not isinstance(widget.value, (Link, Dataset)): + if not isinstance(widget.value, (Link, Dataset, FileWriter)): stream_module = deepcopy(widget.value) stream_module.parent_node = component component.children.append(stream_module) diff --git a/nexus_constructor/common_attrs.py b/nexus_constructor/common_attrs.py index 3aa4d8d5e..cbedf1a70 100644 --- a/nexus_constructor/common_attrs.py +++ b/nexus_constructor/common_attrs.py @@ -41,6 +41,7 @@ class TransformationType: SAMPLE_NAME = "sample" ARRAY = "Array" SCALAR = "Scalar" +FILEWRITER = "Filewriter" SHAPE_GROUP_NAME = "shape" PIXEL_SHAPE_GROUP_NAME = "pixel_shape" GEOMETRY_GROUP_NAME = "geometry" diff --git a/nexus_constructor/field_utils.py b/nexus_constructor/field_utils.py index 36fd098a2..7f2ef8b47 100644 --- a/nexus_constructor/field_utils.py +++ b/nexus_constructor/field_utils.py @@ -7,7 +7,7 @@ from nexus_constructor.field_widget import FieldWidget from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES from nexus_constructor.model.group import Group -from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule +from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule, FileWriter from nexus_constructor.model.value_type import ValueTypes from nexus_constructor.utils.required_component_fields import required_component_fields from nexus_constructor.validators import FieldType @@ -47,7 +47,17 @@ def __update_existing_dataset_field(field: Dataset, new_ui_field: FieldWidget): new_ui_field.value = field.values # type: ignore new_ui_field.attrs = field units = field.attributes.get_attribute_value(CommonAttrs.UNITS) - new_ui_field.units = units + new_ui_field.units = units or "" + + +def update_existing_filewriter_field(field: Dataset, new_ui_field: FieldWidget): + """ + Fill in a UI filewriter field for an existing filewriter field in the component group + :param field: The dataset to copy into the ???value line edit + :param new_ui_field: The new UI field to fill in with existing data + """ + new_ui_field.field_type = FieldType(FieldType.filewriter.value) + __update_existing_dataset_field(field, new_ui_field) def update_existing_scalar_field(field: Dataset, new_ui_field: FieldWidget): @@ -69,7 +79,7 @@ def update_existing_stream_field( :param new_ui_field: The new UI field to fill in with existing data """ new_ui_field.field_type = FieldType.kafka_stream - new_ui_field._old_schema = field.writer_module # type: ignore + new_ui_field._old_schema = field.writer_module new_ui_field.streams_widget.update_existing_stream_info(field) new_ui_field.attrs = field units = field.attributes.get_attribute_value(CommonAttrs.UNITS) @@ -115,6 +125,8 @@ def find_field_type(item: "ValueType", ignore_names=INVALID_FIELD_NAMES) -> Call return update_existing_stream_field elif isinstance(item, Link): return update_existing_link_field + elif isinstance(item,FileWriter): + return update_existing_filewriter_field else: try: logging.debug( diff --git a/nexus_constructor/field_widget.py b/nexus_constructor/field_widget.py index 681787b48..0c8161a69 100644 --- a/nexus_constructor/field_widget.py +++ b/nexus_constructor/field_widget.py @@ -25,7 +25,7 @@ from nexus_constructor.field_attrs import FieldAttrsDialog from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES from nexus_constructor.model.group import Group -from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule +from nexus_constructor.model.module import Dataset, FileWriter, FileWriterModule, Link, StreamModule from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP, ValueTypes from nexus_constructor.stream_fields_widget import StreamFieldsWidget from nexus_constructor.ui_utils import validate_line_edit @@ -367,6 +367,12 @@ def value(self) -> Union[FileWriterModule, None]: name=self.name, source=self.value_line_edit.text(), ) + elif self.field_type == FieldType.filewriter: + return_object = FileWriter( + parent_node=self._node_parent, + name=self.name, + type=dtype, + ) else: logging.error(f"unknown field type: {self.name}") return None @@ -450,14 +456,10 @@ def field_type_changed(self): self.streams_widget.ok_validator.validate_ok() self.streams_widget.cancel_button.clicked.connect(self.reset_field_type) elif self.field_type == FieldType.link: - self.set_visibility( - True, - False, - False, - False, - show_unit_line_edit=False, - show_attrs_edit=False, - ) + self.set_visibility(True, False, False, False, show_unit_line_edit=False, show_attrs_edit=False) + self._set_up_value_validator(False) + elif self.field_type == FieldType.filewriter: + self.set_visibility(False, False, False, False, True, False, False) self._set_up_value_validator(False) def reset_field_type(self): @@ -488,7 +490,7 @@ def _set_up_value_validator(self, is_link: bool): FieldValueValidator( self.field_type_combo, self.value_type_combo, - FieldType.scalar_dataset.value, + self.field_type.value ) ) tooltip_on_accept = "Value is cast-able to numpy type." diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py index ec4f44401..57dc6f9d9 100644 --- a/nexus_constructor/json/load_from_json.py +++ b/nexus_constructor/json/load_from_json.py @@ -43,6 +43,7 @@ from nexus_constructor.model.model import Model from nexus_constructor.model.module import ( Dataset, + FileWriter, FileWriterModule, Link, StreamModule, @@ -276,7 +277,7 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None): elif CommonKeys.MODULE in json_object and NodeType.CONFIG in json_object: module_type = json_object[CommonKeys.MODULE] if ( - module_type == WriterModules.DATASET.value + ( module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value ) and json_object[NodeType.CONFIG][CommonKeys.NAME] == CommonAttrs.DEPENDS_ON ): diff --git a/nexus_constructor/model/module.py b/nexus_constructor/model/module.py index 27327389f..ac87761f9 100644 --- a/nexus_constructor/model/module.py +++ b/nexus_constructor/model/module.py @@ -39,6 +39,7 @@ class WriterModules(Enum): LINK = "link" DATASET = "dataset" ADAR = "ADAr" + FILEWRITER = "filewriter" class StreamModules(Enum): @@ -167,6 +168,24 @@ class F144Stream(F142Stream): writer_module = attr.ib(type=str, default=WriterModules.F144.value, init=False) +@attr.s +class FileWriter(FileWriterModule): + name = attr.ib(type=str) + type = attr.ib(type=str, default="string") + values = attr.ib(type=str, default=None) + writer_module = attr.ib(type=str, default=WriterModules.FILEWRITER.value, init=False) + + def as_dict(self, error_collector: List[str]): + return { + CommonKeys.MODULE: self.writer_module, + NodeType.CONFIG: {CommonKeys.NAME: self.name}, + } + + def as_nexus(self, nexus_node, error_collector: List[str]): + nexus_dataset = nexus_node.create_dataset(self.name, data=self.name) + nexus_dataset.attrs[self.name] = self.name + + @attr.s class Link(FileWriterModule): name = attr.ib(type=str) @@ -305,6 +324,7 @@ class WriterModuleClasses(Enum): LINK = Link DATASET = Dataset ADAR = ADARStream + FILEWRITER = FileWriter module_class_dict = dict( @@ -373,6 +393,12 @@ def create_fw_module_object(mod_type, configuration, parent_node): source=configuration[SOURCE], parent_node=parent_node, ) + elif mod_type == WriterModules.FILEWRITER.value: + fw_mod_obj = fw_mod_class( + name=configuration[CommonKeys.NAME], + parent_node=parent_node, + type="string" + ) elif mod_type == WriterModules.DATASET.value: if CommonKeys.DATA_TYPE in configuration: dtype = configuration[CommonKeys.DATA_TYPE] diff --git a/nexus_constructor/module_view.py b/nexus_constructor/module_view.py index 878b1375c..642b27f70 100644 --- a/nexus_constructor/module_view.py +++ b/nexus_constructor/module_view.py @@ -31,7 +31,7 @@ def _setup_frame(self, module): source = module.source if module.source else "not specified" self.layout.addWidget(self._get_label(f"link name: {name} | ")) self.layout.addWidget(self._get_label(f"source: {source}")) - elif module.writer_module == WriterModules.DATASET.value: + elif module.writer_module == WriterModules.DATASET.value or module.writer_module == WriterModules.FILEWRITER.value: name = module.name if module.name else "not specified" dtype = module.type if module.type else "not specified" self.layout.addWidget(self._get_label(f"dataset name: {name} | ")) @@ -74,8 +74,8 @@ def _set_existing_items(self): if ( self.module.writer_module == WriterModules.DATASET.value or self.module.writer_module == WriterModules.LINK.value - or self.module.writer_module - in [StreamMode.value for StreamMode in StreamModules] + or self.module.writer_module in [StreamMode.value for StreamMode in StreamModules] + or self.module.writer_module == WriterModules.FILEWRITER.value ): update_function = find_field_type(module, []) if update_function is not None: diff --git a/nexus_constructor/ui_utils.py b/nexus_constructor/ui_utils.py index 3fd8d10eb..8b9a3d08a 100644 --- a/nexus_constructor/ui_utils.py +++ b/nexus_constructor/ui_utils.py @@ -61,7 +61,7 @@ def validate_combobox_edit( :param tooltip_on_reject: Tooltip to display combobox edit is invalid. :return: None. """ - colour = "#FFFFFF" if is_valid else "#f6989d" + colour = "#333333" if is_valid else "#f6989d" combobox_edit.setStyleSheet(f"QComboBox {{ background-color: {colour} }}") if "Suggestion" in tooltip_on_reject and callable(suggestion_callable): tooltip_on_reject += suggestion_callable() @@ -86,7 +86,7 @@ def validate_line_edit( :param tooltip_on_reject: Tooltip to display if line edit is invalid. :return: None. """ - colour = "#FFFFFF" if is_valid else "#f6989d" + colour = "#333333" if is_valid else "#f6989d" line_edit.setStyleSheet(f"QLineEdit {{ background-color: {colour} }}") if "Suggestion" in tooltip_on_reject and callable(suggestion_callable): tooltip_on_reject += suggestion_callable() diff --git a/nexus_constructor/validators.py b/nexus_constructor/validators.py index 996369e1e..fba06dc15 100644 --- a/nexus_constructor/validators.py +++ b/nexus_constructor/validators.py @@ -10,7 +10,7 @@ from PySide6.QtWidgets import QComboBox, QListWidget, QRadioButton, QWidget from stl import mesh -from nexus_constructor.common_attrs import SCALAR +from nexus_constructor.common_attrs import SCALAR, FILEWRITER from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP from nexus_constructor.unit_utils import ( units_are_expected_dimensionality, @@ -392,6 +392,8 @@ class FieldType(Enum): array_dataset = "Array dataset" kafka_stream = "Kafka stream" link = "Link" + filewriter = "Filewriter" + class FieldValueValidator(QValidator): @@ -417,9 +419,9 @@ def validate(self, input: str, pos: int) -> QValidator.State: :param pos: mouse position cursor(ignored, just here to satisfy overriding function) :return: QValidator state (Acceptable, Intermediate, Invalid) - returning intermediate because invalid stops the user from typing. """ - if not input: # More criteria here + if not input and not self.scalar == FILEWRITER: # More criteria here return self._emit_and_return(False) - if self.field_type_combo.currentText() == self.scalar: + if self.field_type_combo.currentText() == SCALAR: try: VALUE_TYPE_TO_NP[self.dataset_type_combo.currentText()](input) except ValueError: diff --git a/requirements.txt b/requirements.txt index a921a837e..8d10cbf48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,12 @@ nexusformat numpy numpy-stl -open3d +#lightgbm for macOS should instead be installed via (brew/port) install libomp (needed for open3d) +open3d #installs a binary linked to homebrew; make a directory and symlink, e.g. ln -s /opt/local/lib/libomp/libomp.dylib /opt/homebrew/opt/libomp/lib/libomp.dylib pint PySide6<6.4.0 pytest-qt xmltodict h5py ess-streaming-data-types >= 0.9.5 +attrs \ No newline at end of file diff --git a/ui/main_window.py b/ui/main_window.py index c80d3f15d..d2ef33c31 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -20,6 +20,7 @@ class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.resize(1280, 720) + MainWindow.setStyleSheet("* {color: #000000;background-color: #999999;}") self.central_widget = QWidget(MainWindow) self.splitter = QSplitter(self.central_widget) From 5de59ffc0328ec55d6ebd21b525caa19cdbe662e Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Fri, 9 Jun 2023 19:34:23 +0200 Subject: [PATCH 05/13] correct colour in tests (for dark mode visibility) --- tests/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index f939309bb..b523fbbea 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -24,7 +24,7 @@ def test_GIVEN_invalid_WHEN_validating_line_edit_THEN_line_edit_turns_red(): def test_GIVEN_valid_WHEN_validating_line_edit_THEN_line_edit_turns_white(): line_edit = DummyLineEdit() validate_line_edit(line_edit, True) - assert "background-color: #FFFFFF" in line_edit.stylesheet + assert "background-color: #333333" in line_edit.stylesheet def test_GIVEN_valid_WHEN_validating_line_edit_with_tooltip_THEN_line_edit_tooltip_is_changed(): From f59eb33625ec6e3f25ecd450b771e94489e97a75 Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Mon, 12 Jun 2023 18:04:22 +0200 Subject: [PATCH 06/13] added test, altered pint version, all successful --- nexus_constructor/validators.py | 2 +- requirements.txt | 2 +- tests/test_validators.py | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/nexus_constructor/validators.py b/nexus_constructor/validators.py index fba06dc15..f8996d972 100644 --- a/nexus_constructor/validators.py +++ b/nexus_constructor/validators.py @@ -421,7 +421,7 @@ def validate(self, input: str, pos: int) -> QValidator.State: """ if not input and not self.scalar == FILEWRITER: # More criteria here return self._emit_and_return(False) - if self.field_type_combo.currentText() == SCALAR: + if self.field_type_combo.currentText() == self.scalar: try: VALUE_TYPE_TO_NP[self.dataset_type_combo.currentText()](input) except ValueError: diff --git a/requirements.txt b/requirements.txt index 8d10cbf48..3480f22d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ numpy numpy-stl #lightgbm for macOS should instead be installed via (brew/port) install libomp (needed for open3d) open3d #installs a binary linked to homebrew; make a directory and symlink, e.g. ln -s /opt/local/lib/libomp/libomp.dylib /opt/homebrew/opt/libomp/lib/libomp.dylib -pint +pint<=0.21 PySide6<6.4.0 pytest-qt xmltodict diff --git a/tests/test_validators.py b/tests/test_validators.py index 0b509002b..461bbee75 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -172,6 +172,19 @@ def test_GIVEN_valid_string_value_WHEN_validating_field_value_THEN_returns_accep assert validator.validate(strvalue, 0) == QValidator.Acceptable validator.is_valid.emit.assert_called_once_with(True) +def test_GIVEN_valid_name_value_WHEN_validating_filewriter_THEN_returns_acceptable_and_emits_signal_with_true(): + strvalue = "123a" + + field_type_combo = DummyCombo(FieldType.filewriter.value) + dataset_type_combo = DummyCombo(ValueTypes.STRING) + + validator = FieldValueValidator( + field_type_combo, dataset_type_combo, FieldType.filewriter.value + ) + validator.is_valid = Mock() + + assert validator.validate(strvalue, 0) == QValidator.Acceptable + validator.is_valid.emit.assert_called_once_with(True) def test_GIVEN_invalid_float_value_WHEN_validating_field_value_THEN_returns_intermediate_and_emits_signal_with_false(): invalid_value = "sdfn" From 7af08cf320540287cbef012aacd44832135c2638 Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Mon, 12 Jun 2023 18:22:24 +0200 Subject: [PATCH 07/13] Cleaned up code as per flake8 --- nexus_constructor/field_utils.py | 2 +- nexus_constructor/json/load_from_json.py | 4 ++-- nexus_constructor/validators.py | 1 - tests/test_validators.py | 2 ++ 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/nexus_constructor/field_utils.py b/nexus_constructor/field_utils.py index 7f2ef8b47..2117ce07f 100644 --- a/nexus_constructor/field_utils.py +++ b/nexus_constructor/field_utils.py @@ -125,7 +125,7 @@ def find_field_type(item: "ValueType", ignore_names=INVALID_FIELD_NAMES) -> Call return update_existing_stream_field elif isinstance(item, Link): return update_existing_link_field - elif isinstance(item,FileWriter): + elif isinstance(item, FileWriter): return update_existing_filewriter_field else: try: diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py index 57dc6f9d9..24ad1a2ac 100644 --- a/nexus_constructor/json/load_from_json.py +++ b/nexus_constructor/json/load_from_json.py @@ -202,7 +202,7 @@ def _load_from_json_dict(self, json_dict: Dict) -> bool: self.entry_node = self._read_json_object(json_dict[CommonKeys.CHILDREN][0]) self.model.entry.attributes = self.entry_node.attributes for child in self.entry_node.children: - if isinstance(child, (Dataset, Link, Group)): + if isinstance(child, (Dataset, Link, FileWriter, Group)): self.model.entry[child.name] = child else: self.model.entry.children.append(child) @@ -277,7 +277,7 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None): elif CommonKeys.MODULE in json_object and NodeType.CONFIG in json_object: module_type = json_object[CommonKeys.MODULE] if ( - ( module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value ) + (module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value) and json_object[NodeType.CONFIG][CommonKeys.NAME] == CommonAttrs.DEPENDS_ON ): diff --git a/nexus_constructor/validators.py b/nexus_constructor/validators.py index f8996d972..f3692552b 100644 --- a/nexus_constructor/validators.py +++ b/nexus_constructor/validators.py @@ -395,7 +395,6 @@ class FieldType(Enum): filewriter = "Filewriter" - class FieldValueValidator(QValidator): """ Validates the field value line edit to check that the entered string is castable to the selected numpy type. diff --git a/tests/test_validators.py b/tests/test_validators.py index 461bbee75..b2a8cdb92 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -172,6 +172,7 @@ def test_GIVEN_valid_string_value_WHEN_validating_field_value_THEN_returns_accep assert validator.validate(strvalue, 0) == QValidator.Acceptable validator.is_valid.emit.assert_called_once_with(True) + def test_GIVEN_valid_name_value_WHEN_validating_filewriter_THEN_returns_acceptable_and_emits_signal_with_true(): strvalue = "123a" @@ -186,6 +187,7 @@ def test_GIVEN_valid_name_value_WHEN_validating_filewriter_THEN_returns_acceptab assert validator.validate(strvalue, 0) == QValidator.Acceptable validator.is_valid.emit.assert_called_once_with(True) + def test_GIVEN_invalid_float_value_WHEN_validating_field_value_THEN_returns_intermediate_and_emits_signal_with_false(): invalid_value = "sdfn" From c7f925953501409a8f6df10ece6acc9179ee82ac Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Tue, 13 Jun 2023 16:00:03 +0200 Subject: [PATCH 08/13] Changed styling --- nexus-constructor.py | 1 + ui/UI.md | 13 ------------- ui/main_window.py | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 ui/UI.md diff --git a/nexus-constructor.py b/nexus-constructor.py index b0c8c41b8..bead28395 100644 --- a/nexus-constructor.py +++ b/nexus-constructor.py @@ -75,6 +75,7 @@ def closeEvent(self, event: QCloseEvent) -> None: if "help" in parser.parse_args(): exit(0) logging.basicConfig(level=logging.INFO) + QApplication.setStyle("Fusion") QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) surfaceFormat = QSurfaceFormat() surfaceFormat.setSwapInterval(1) diff --git a/ui/UI.md b/ui/UI.md deleted file mode 100644 index 500cc5e81..000000000 --- a/ui/UI.md +++ /dev/null @@ -1,13 +0,0 @@ -#ui/ - -This directory contains auto-generated python files and UI files to be used with Qt Creator/Qt Designer. - -Use `pyside2-uic uifile.ui -o pythonfile.py` to convert the .ui files to python with the same name. - - -## Known issues when using pyside2-uic -Some of the UI components don't seem to generate the correct import statements when using `pyside2-uic`. They paste the incorrect import statement underneath the code for some reason. - - -- [QWebEngine](https://bugreports.qt.io/browse/PYSIDE-1020) - - workaround - paste in `from PySide2.QtWebEngineWidgets import QWebEngineView` and remove the incorrect import statement diff --git a/ui/main_window.py b/ui/main_window.py index d2ef33c31..08340f9de 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -20,7 +20,7 @@ class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.resize(1280, 720) - MainWindow.setStyleSheet("* {color: #000000;background-color: #999999;}") +# MainWindow.setStyleSheet("* {color: #000000;background-color: #999999;}") # style set instead in nexus-constructor.py:78:QApplication.setStyle("Fusion") self.central_widget = QWidget(MainWindow) self.splitter = QSplitter(self.central_widget) From 8f6137206c49b3ff41ae6fcf2b58ea723a88c467 Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Tue, 13 Jun 2023 16:08:17 +0200 Subject: [PATCH 09/13] corrected white_background to new off-white colour --- ui_tests/ui_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui_tests/ui_test_utils.py b/ui_tests/ui_test_utils.py index 0d1327410..6805d9348 100644 --- a/ui_tests/ui_test_utils.py +++ b/ui_tests/ui_test_utils.py @@ -7,7 +7,7 @@ RUNNING_ON_WINDOWS = sys.platform.startswith("win") RED_BACKGROUND = "{ background-color: #f6989d }" -WHITE_BACKGROUND = "{ background-color: #FFFFFF }" +WHITE_BACKGROUND = "{ background-color: #333333 }" # no longer white LINE_EDIT = "QLineEdit " SPIN_BOX = "QSpinBox " RED_LINE_EDIT_STYLE_SHEET = LINE_EDIT + RED_BACKGROUND From ba5e2c1f5bba951b5e83e2725be11a73bf78ca91 Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Tue, 13 Jun 2023 16:23:59 +0200 Subject: [PATCH 10/13] flake8 format --- ui_tests/ui_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui_tests/ui_test_utils.py b/ui_tests/ui_test_utils.py index 6805d9348..522df0f51 100644 --- a/ui_tests/ui_test_utils.py +++ b/ui_tests/ui_test_utils.py @@ -7,7 +7,7 @@ RUNNING_ON_WINDOWS = sys.platform.startswith("win") RED_BACKGROUND = "{ background-color: #f6989d }" -WHITE_BACKGROUND = "{ background-color: #333333 }" # no longer white +WHITE_BACKGROUND = "{ background-color: #333333 }" # no longer white LINE_EDIT = "QLineEdit " SPIN_BOX = "QSpinBox " RED_LINE_EDIT_STYLE_SHEET = LINE_EDIT + RED_BACKGROUND From e87393c2491abc2483622c1c0021a2fb5555462f Mon Sep 17 00:00:00 2001 From: George O'Neill Date: Tue, 13 Jun 2023 17:09:05 +0200 Subject: [PATCH 11/13] fixed SSL error for HTML documentation build, filewriter to JSON --- definitions/requirements.txt | 1 + tests/json/test_load_from_json.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/definitions/requirements.txt b/definitions/requirements.txt index bded64d61..6492a2e43 100644 --- a/definitions/requirements.txt +++ b/definitions/requirements.txt @@ -1,3 +1,4 @@ lxml pyRestTable==2020.0.3 +urllib3<2.0 Sphinx diff --git a/tests/json/test_load_from_json.py b/tests/json/test_load_from_json.py index 57e7a2c61..f116d111e 100644 --- a/tests/json/test_load_from_json.py +++ b/tests/json/test_load_from_json.py @@ -45,7 +45,7 @@ def nexus_json_dictionary() -> dict: "values":"NXinstrument" }], "children":[ - + ] }, { @@ -62,10 +62,16 @@ def nexus_json_dictionary() -> dict: "type":"group", "name":"transformations", "children":[ - + ] } ] + }, + { + "module": "filewriter", + "config": { + "name": "start_time" + } } ] } @@ -117,7 +123,7 @@ def json_dict_with_component(): "type":"group", "name":"transformations", "children":[ - + ] } ] @@ -139,7 +145,7 @@ def json_dict_with_component(): "type":"group", "name":"transformations", "children":[ - + ] } ] @@ -289,7 +295,7 @@ def test_GIVEN_json_with_missing_value_WHEN_loading_from_json_THEN_json_loader_r "values":"NXinstrument" }, "children":[ - + ] }, { @@ -306,7 +312,7 @@ def test_GIVEN_json_with_missing_value_WHEN_loading_from_json_THEN_json_loader_r "type":"group", "name":"transformations", "children":[ - + ] } ] From 751d57ee499d539382e66e3d0cd9fb0a64a1f3ab Mon Sep 17 00:00:00 2001 From: cow-bot Date: Tue, 13 Jun 2023 15:13:09 +0000 Subject: [PATCH 12/13] GO FORMAT YOURSELF (black) --- nexus_constructor/field_utils.py | 8 +++++++- nexus_constructor/field_widget.py | 21 ++++++++++++++++----- nexus_constructor/json/load_from_json.py | 9 +++++---- nexus_constructor/model/module.py | 8 ++++---- nexus_constructor/module_view.py | 8 ++++++-- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/nexus_constructor/field_utils.py b/nexus_constructor/field_utils.py index 2117ce07f..da79e0c27 100644 --- a/nexus_constructor/field_utils.py +++ b/nexus_constructor/field_utils.py @@ -7,7 +7,13 @@ from nexus_constructor.field_widget import FieldWidget from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES from nexus_constructor.model.group import Group -from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule, FileWriter +from nexus_constructor.model.module import ( + Dataset, + FileWriterModule, + Link, + StreamModule, + FileWriter, +) from nexus_constructor.model.value_type import ValueTypes from nexus_constructor.utils.required_component_fields import required_component_fields from nexus_constructor.validators import FieldType diff --git a/nexus_constructor/field_widget.py b/nexus_constructor/field_widget.py index 0c8161a69..0eda46af7 100644 --- a/nexus_constructor/field_widget.py +++ b/nexus_constructor/field_widget.py @@ -25,7 +25,13 @@ from nexus_constructor.field_attrs import FieldAttrsDialog from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES from nexus_constructor.model.group import Group -from nexus_constructor.model.module import Dataset, FileWriter, FileWriterModule, Link, StreamModule +from nexus_constructor.model.module import ( + Dataset, + FileWriter, + FileWriterModule, + Link, + StreamModule, +) from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP, ValueTypes from nexus_constructor.stream_fields_widget import StreamFieldsWidget from nexus_constructor.ui_utils import validate_line_edit @@ -456,7 +462,14 @@ def field_type_changed(self): self.streams_widget.ok_validator.validate_ok() self.streams_widget.cancel_button.clicked.connect(self.reset_field_type) elif self.field_type == FieldType.link: - self.set_visibility(True, False, False, False, show_unit_line_edit=False, show_attrs_edit=False) + self.set_visibility( + True, + False, + False, + False, + show_unit_line_edit=False, + show_attrs_edit=False, + ) self._set_up_value_validator(False) elif self.field_type == FieldType.filewriter: self.set_visibility(False, False, False, False, True, False, False) @@ -488,9 +501,7 @@ def _set_up_value_validator(self, is_link: bool): else: self.value_line_edit.setValidator( FieldValueValidator( - self.field_type_combo, - self.value_type_combo, - self.field_type.value + self.field_type_combo, self.value_type_combo, self.field_type.value ) ) tooltip_on_accept = "Value is cast-able to numpy type." diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py index 24ad1a2ac..56051ef0c 100644 --- a/nexus_constructor/json/load_from_json.py +++ b/nexus_constructor/json/load_from_json.py @@ -277,10 +277,11 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None): elif CommonKeys.MODULE in json_object and NodeType.CONFIG in json_object: module_type = json_object[CommonKeys.MODULE] if ( - (module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value) - and json_object[NodeType.CONFIG][CommonKeys.NAME] - == CommonAttrs.DEPENDS_ON - ): + module_type == WriterModules.DATASET.value + or module_type == WriterModules.FILEWRITER.value + ) and json_object[NodeType.CONFIG][ + CommonKeys.NAME + ] == CommonAttrs.DEPENDS_ON: nexus_object = None elif module_type in [x.value for x in WriterModules]: nexus_object = create_fw_module_object( diff --git a/nexus_constructor/model/module.py b/nexus_constructor/model/module.py index ac87761f9..1219310b2 100644 --- a/nexus_constructor/model/module.py +++ b/nexus_constructor/model/module.py @@ -173,7 +173,9 @@ class FileWriter(FileWriterModule): name = attr.ib(type=str) type = attr.ib(type=str, default="string") values = attr.ib(type=str, default=None) - writer_module = attr.ib(type=str, default=WriterModules.FILEWRITER.value, init=False) + writer_module = attr.ib( + type=str, default=WriterModules.FILEWRITER.value, init=False + ) def as_dict(self, error_collector: List[str]): return { @@ -395,9 +397,7 @@ def create_fw_module_object(mod_type, configuration, parent_node): ) elif mod_type == WriterModules.FILEWRITER.value: fw_mod_obj = fw_mod_class( - name=configuration[CommonKeys.NAME], - parent_node=parent_node, - type="string" + name=configuration[CommonKeys.NAME], parent_node=parent_node, type="string" ) elif mod_type == WriterModules.DATASET.value: if CommonKeys.DATA_TYPE in configuration: diff --git a/nexus_constructor/module_view.py b/nexus_constructor/module_view.py index 642b27f70..bb792a583 100644 --- a/nexus_constructor/module_view.py +++ b/nexus_constructor/module_view.py @@ -31,7 +31,10 @@ def _setup_frame(self, module): source = module.source if module.source else "not specified" self.layout.addWidget(self._get_label(f"link name: {name} | ")) self.layout.addWidget(self._get_label(f"source: {source}")) - elif module.writer_module == WriterModules.DATASET.value or module.writer_module == WriterModules.FILEWRITER.value: + elif ( + module.writer_module == WriterModules.DATASET.value + or module.writer_module == WriterModules.FILEWRITER.value + ): name = module.name if module.name else "not specified" dtype = module.type if module.type else "not specified" self.layout.addWidget(self._get_label(f"dataset name: {name} | ")) @@ -74,7 +77,8 @@ def _set_existing_items(self): if ( self.module.writer_module == WriterModules.DATASET.value or self.module.writer_module == WriterModules.LINK.value - or self.module.writer_module in [StreamMode.value for StreamMode in StreamModules] + or self.module.writer_module + in [StreamMode.value for StreamMode in StreamModules] or self.module.writer_module == WriterModules.FILEWRITER.value ): update_function = find_field_type(module, []) From b63623f02dd4dbcc60864fab5cb18b5980ad2c9c Mon Sep 17 00:00:00 2001 From: cow-bot Date: Tue, 13 Jun 2023 15:14:22 +0000 Subject: [PATCH 13/13] Update NeXus HTML documentation --- .../html/applying-nexus.html | 5 +- nx-class-documentation/html/authorgroup.html | 5 +- .../html/classes/applications/NXarchive.html | 5 +- .../html/classes/applications/NXarpes.html | 5 +- .../html/classes/applications/NXcanSAS.html | 9 ++- .../classes/applications/NXdirecttof.html | 5 +- .../html/classes/applications/NXfluo.html | 5 +- .../classes/applications/NXindirecttof.html | 5 +- .../html/classes/applications/NXiqproc.html | 5 +- .../html/classes/applications/NXlauetof.html | 5 +- .../html/classes/applications/NXmonopd.html | 5 +- .../html/classes/applications/NXmx.html | 5 +- .../html/classes/applications/NXrefscan.html | 5 +- .../html/classes/applications/NXreftof.html | 5 +- .../html/classes/applications/NXsas.html | 5 +- .../html/classes/applications/NXsastof.html | 5 +- .../html/classes/applications/NXscan.html | 5 +- .../html/classes/applications/NXspe.html | 5 +- .../html/classes/applications/NXsqom.html | 5 +- .../html/classes/applications/NXstxm.html | 5 +- .../html/classes/applications/NXtas.html | 5 +- .../html/classes/applications/NXtofnpd.html | 5 +- .../html/classes/applications/NXtofraw.html | 5 +- .../classes/applications/NXtofsingle.html | 5 +- .../html/classes/applications/NXtomo.html | 5 +- .../classes/applications/NXtomophase.html | 5 +- .../html/classes/applications/NXtomoproc.html | 5 +- .../html/classes/applications/NXxas.html | 5 +- .../html/classes/applications/NXxasproc.html | 5 +- .../html/classes/applications/NXxbase.html | 5 +- .../html/classes/applications/NXxeuler.html | 5 +- .../html/classes/applications/NXxkappa.html | 5 +- .../html/classes/applications/NXxlaue.html | 5 +- .../classes/applications/NXxlaueplate.html | 5 +- .../html/classes/applications/NXxnb.html | 5 +- .../html/classes/applications/NXxrot.html | 5 +- .../html/classes/applications/index.html | 5 +- .../html/classes/base_classes/NXaperture.html | 5 +- .../classes/base_classes/NXattenuator.html | 5 +- .../html/classes/base_classes/NXbeam.html | 5 +- .../classes/base_classes/NXbeam_stop.html | 5 +- .../base_classes/NXbending_magnet.html | 5 +- .../classes/base_classes/NXcapillary.html | 5 +- .../html/classes/base_classes/NXcite.html | 5 +- .../classes/base_classes/NXcollection.html | 5 +- .../classes/base_classes/NXcollimator.html | 5 +- .../html/classes/base_classes/NXcrystal.html | 5 +- .../base_classes/NXcylindrical_geometry.html | 5 +- .../html/classes/base_classes/NXdata.html | 5 +- .../html/classes/base_classes/NXdetector.html | 5 +- .../base_classes/NXdetector_group.html | 5 +- .../base_classes/NXdetector_module.html | 5 +- .../classes/base_classes/NXdisk_chopper.html | 5 +- .../html/classes/base_classes/NXentry.html | 7 +-- .../classes/base_classes/NXenvironment.html | 5 +- .../classes/base_classes/NXevent_data.html | 5 +- .../classes/base_classes/NXfermi_chopper.html | 5 +- .../html/classes/base_classes/NXfilter.html | 5 +- .../html/classes/base_classes/NXflipper.html | 5 +- .../base_classes/NXfresnel_zone_plate.html | 5 +- .../html/classes/base_classes/NXgeometry.html | 5 +- .../html/classes/base_classes/NXgrating.html | 5 +- .../html/classes/base_classes/NXguide.html | 5 +- .../base_classes/NXinsertion_device.html | 5 +- .../classes/base_classes/NXinstrument.html | 5 +- .../html/classes/base_classes/NXlog.html | 5 +- .../html/classes/base_classes/NXmirror.html | 5 +- .../classes/base_classes/NXmoderator.html | 5 +- .../html/classes/base_classes/NXmonitor.html | 5 +- .../classes/base_classes/NXmonochromator.html | 5 +- .../html/classes/base_classes/NXnote.html | 5 +- .../html/classes/base_classes/NXobject.html | 5 +- .../classes/base_classes/NXoff_geometry.html | 5 +- .../classes/base_classes/NXorientation.html | 5 +- .../classes/base_classes/NXparameters.html | 5 +- .../html/classes/base_classes/NXpdb.html | 5 +- .../html/classes/base_classes/NXpinhole.html | 5 +- .../classes/base_classes/NXpolarizer.html | 5 +- .../classes/base_classes/NXpositioner.html | 5 +- .../html/classes/base_classes/NXprocess.html | 5 +- .../classes/base_classes/NXreflections.html | 5 +- .../html/classes/base_classes/NXroot.html | 5 +- .../html/classes/base_classes/NXsample.html | 5 +- .../base_classes/NXsample_component.html | 5 +- .../html/classes/base_classes/NXsensor.html | 5 +- .../html/classes/base_classes/NXshape.html | 5 +- .../html/classes/base_classes/NXslit.html | 5 +- .../html/classes/base_classes/NXsource.html | 5 +- .../html/classes/base_classes/NXsubentry.html | 5 +- .../base_classes/NXtransformations.html | 5 +- .../classes/base_classes/NXtranslation.html | 5 +- .../html/classes/base_classes/NXuser.html | 5 +- .../base_classes/NXvelocity_selector.html | 5 +- .../html/classes/base_classes/NXxraylens.html | 5 +- .../html/classes/base_classes/index.html | 5 +- .../contributed_definitions/NXcontainer.html | 5 +- .../contributed_definitions/NXcsg.html | 5 +- .../contributed_definitions/NXcxi_ptycho.html | 5 +- .../NXelectrostatic_kicker.html | 5 +- .../NXmagnetic_kicker.html | 5 +- .../contributed_definitions/NXquadric.html | 5 +- .../NXquadrupole_magnet.html | 5 +- .../contributed_definitions/NXseparator.html | 5 +- .../contributed_definitions/NXsnsevent.html | 5 +- .../contributed_definitions/NXsnshisto.html | 5 +- .../NXsolenoid_magnet.html | 5 +- .../NXsolid_geometry.html | 5 +- .../contributed_definitions/NXspecdata.html | 7 +-- .../NXspin_rotator.html | 5 +- .../contributed_definitions/index.html | 5 +- .../html/classes/index.html | 7 +-- nx-class-documentation/html/colophon.html | 5 +- nx-class-documentation/html/community.html | 5 +- nx-class-documentation/html/copyright.html | 5 +- nx-class-documentation/html/datarules.html | 23 ++++---- nx-class-documentation/html/defs_intro.html | 7 +-- nx-class-documentation/html/design.html | 20 +++---- nx-class-documentation/html/docs_about.html | 5 +- .../html/examples/code_napi.html | 9 ++- .../html/examples/code_native.html | 5 +- .../html/examples/epics/index.html | 27 +++++---- .../html/examples/h5py/index.html | 13 ++--- .../html/examples/h5py/writer_1_3.html | 7 +-- .../html/examples/h5py/writer_2_1.html | 5 +- .../html/examples/index.html | 5 +- .../html/examples/lrmecs/index.html | 7 +-- .../html/examples/matlab/index.html | 5 +- nx-class-documentation/html/faq.html | 8 +-- nx-class-documentation/html/fileformat.html | 5 +- nx-class-documentation/html/genindex.html | 3 +- nx-class-documentation/html/github.html | 5 +- nx-class-documentation/html/history.html | 11 ++-- nx-class-documentation/html/index.html | 7 +-- nx-class-documentation/html/installation.html | 9 ++- .../html/introduction-napi.html | 21 ++++--- nx-class-documentation/html/introduction.html | 7 +-- nx-class-documentation/html/issues.html | 5 +- nx-class-documentation/html/mailinglist.html | 5 +- nx-class-documentation/html/motivations.html | 5 +- nx-class-documentation/html/napi-c.html | 5 +- nx-class-documentation/html/napi-f77.html | 5 +- nx-class-documentation/html/napi-f90.html | 5 +- nx-class-documentation/html/napi-idl.html | 5 +- nx-class-documentation/html/napi-java.html | 5 +- nx-class-documentation/html/napi.html | 5 +- nx-class-documentation/html/niac.html | 7 +-- nx-class-documentation/html/nxdl-types.html | 5 +- nx-class-documentation/html/nxdl.html | 9 ++- nx-class-documentation/html/nxdl_desc.html | 5 +- nx-class-documentation/html/preface.html | 5 +- nx-class-documentation/html/ref_doc.html | 5 +- nx-class-documentation/html/revhistory.html | 5 +- nx-class-documentation/html/rules.html | 5 +- nx-class-documentation/html/search.html | 3 +- nx-class-documentation/html/searchindex.js | 2 +- nx-class-documentation/html/strategies.html | 5 +- nx-class-documentation/html/user_manual.html | 5 +- nx-class-documentation/html/utilities.html | 57 +++++++++---------- nx-class-documentation/html/validation.html | 5 +- 159 files changed, 403 insertions(+), 559 deletions(-) diff --git a/nx-class-documentation/html/applying-nexus.html b/nx-class-documentation/html/applying-nexus.html index 99ab54dc6..47ed1fa7c 100644 --- a/nx-class-documentation/html/applying-nexus.html +++ b/nx-class-documentation/html/applying-nexus.html @@ -1,13 +1,12 @@ - - + 1.3. Constructing NeXus Files and Application Definitions — nexus v2020.10 documentation @@ -790,7 +789,7 @@

Navigation

\ No newline at end of file diff --git a/nx-class-documentation/html/authorgroup.html b/nx-class-documentation/html/authorgroup.html index 736586ba3..285aabff1 100644 --- a/nx-class-documentation/html/authorgroup.html +++ b/nx-class-documentation/html/authorgroup.html @@ -1,13 +1,12 @@ - - + 9.1. Authors — nexus v2020.10 documentation @@ -152,7 +151,7 @@

Navigation

\ No newline at end of file diff --git a/nx-class-documentation/html/classes/applications/NXarchive.html b/nx-class-documentation/html/classes/applications/NXarchive.html index da46f168f..77f79b58b 100644 --- a/nx-class-documentation/html/classes/applications/NXarchive.html +++ b/nx-class-documentation/html/classes/applications/NXarchive.html @@ -1,13 +1,12 @@ - - + 3.3.2.1. NXarchive — nexus v2020.10 documentation @@ -451,7 +450,7 @@

Navigation

\ No newline at end of file diff --git a/nx-class-documentation/html/classes/applications/NXarpes.html b/nx-class-documentation/html/classes/applications/NXarpes.html index 8f214dd91..8b6d450eb 100644 --- a/nx-class-documentation/html/classes/applications/NXarpes.html +++ b/nx-class-documentation/html/classes/applications/NXarpes.html @@ -1,13 +1,12 @@ - - + 3.3.2.2. NXarpes — nexus v2020.10 documentation @@ -370,7 +369,7 @@

Navigation

\ No newline at end of file diff --git a/nx-class-documentation/html/classes/applications/NXcanSAS.html b/nx-class-documentation/html/classes/applications/NXcanSAS.html index b93292b91..fb1b7bfdb 100644 --- a/nx-class-documentation/html/classes/applications/NXcanSAS.html +++ b/nx-class-documentation/html/classes/applications/NXcanSAS.html @@ -1,13 +1,12 @@ - - + 3.3.2.3. NXcanSAS — nexus v2020.10 documentation @@ -192,7 +191,7 @@

Navigation

Use the Unidata UDunits [1] specification as this is compatible with various community standards.