diff --git a/atef/ui/config_window.ui b/atef/ui/config_window.ui index 39427de7..c14c9aea 100644 --- a/atef/ui/config_window.ui +++ b/atef/ui/config_window.ui @@ -37,6 +37,8 @@ File + + @@ -120,6 +122,11 @@ Find / Replace + + + Welcome Tab + + diff --git a/atef/widgets/config/data_passive.py b/atef/widgets/config/data_passive.py index ed53ff3c..10d52f72 100644 --- a/atef/widgets/config/data_passive.py +++ b/atef/widgets/config/data_passive.py @@ -637,6 +637,17 @@ def new_if_disc_combo(self, value: str) -> None: self.bridge.if_disconnected.put(Severity[value]) +def float_or_none(value): + """ + Returns a float, or if value is None, return None. + a "from_str" function for optional values + """ + if value in ('', None): + return None + + return float(value) + + class EqualsMixin: """ Utilities for atol/rtol style data widgets @@ -679,13 +690,13 @@ def setup_equals_widget(self) -> None: setup_line_edit_data( line_edit=self.atol_edit, value_obj=self.bridge.atol, - from_str=float, + from_str=float_or_none, to_str=str, ) setup_line_edit_data( line_edit=self.rtol_edit, value_obj=self.bridge.rtol, - from_str=float, + from_str=float_or_none, to_str=str, ) starting_value = self.bridge.value.get() @@ -865,6 +876,12 @@ def setup_range_widget(self) -> None: self.update_symbols(self.bridge.inclusive.get()) # One additional visual update on inversion self.bridge.invert.changed_value.connect(self.update_visualization) + + # update on value changes + self.bridge.low.changed_value.connect(self.update_visualization) + self.bridge.high.changed_value.connect(self.update_visualization) + self.bridge.warn_low.changed_value.connect(self.update_visualization) + self.bridge.warn_high.changed_value.connect(self.update_visualization) # Make sure this was called at least once self.update_visualization() @@ -969,11 +986,16 @@ def update_visualization(self, *args, **kwargs) -> None: self.vertical_line_3.show() self.warn_low_label.show() self.warn_high_label.show() + # update labels + self.warn_high_label.setText(str(warn_high_mark)) + self.warn_low_label.setText(str(warn_low_mark)) # The yellow and green lines should be sized relative to each other total_range = high_mark - low_mark left_range = warn_low_mark - low_mark mid_range = warn_high_mark - warn_low_mark right_range = high_mark - warn_high_mark + self.low_label.setText(str(low_mark)) + self.high_label.setText(str(high_mark)) self.left_yellow_line.setFixedWidth(int( real_space * left_range/total_range )) diff --git a/atef/widgets/config/page.py b/atef/widgets/config/page.py index 6c265d15..20411c15 100644 --- a/atef/widgets/config/page.py +++ b/atef/widgets/config/page.py @@ -1672,7 +1672,7 @@ def replace_step( if found_row is None: return - step_row = ComparisonRowWidget(data=new_step) + step_row = ConfigurationGroupRowWidget(data=new_step) self.setup_row_buttons( row_widget=step_row, item=comp_item, @@ -1791,12 +1791,16 @@ def select_step_type(self, new_type_index: int) -> None: return step = cast_dataclass(data=self.data, new_type=new_type) + # Assumes self.parent_tree_item.widget: ProcedureGroupPage + # put another way, this assumes steps cannot be parent of other steps self.parent_tree_item.widget.replace_step( old_step=self.data, new_step=step, comp_item=self.tree_item, ) self.tree_item.setText(1, new_type.__name__) + # remove old children, no longer needed. + self.tree_item.takeChildren() self.new_step(step=step) self.update_context() diff --git a/atef/widgets/config/window.py b/atef/widgets/config/window.py index 49789203..f1ae02a5 100644 --- a/atef/widgets/config/window.py +++ b/atef/widgets/config/window.py @@ -58,6 +58,7 @@ class Window(DesignerDisplay, QMainWindow): user_filename_ext = 'json' tab_widget: QTabWidget + action_welcome_tab: QAction action_new_file: QAction action_open_file: QAction action_save: QAction @@ -72,6 +73,7 @@ class Window(DesignerDisplay, QMainWindow): def __init__(self, *args, show_welcome: bool = True, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('atef config') + self.action_welcome_tab.triggered.connect(self.welcome_user) self.action_new_file.triggered.connect(self.new_file) self.action_open_file.triggered.connect(self.open_file) self.action_save.triggered.connect(self.save) @@ -234,6 +236,13 @@ def open_file(self, *args, filename: Optional[str] = None, **kwargs): except ValidationError: logger.error('failed to open file as either active ' 'or passive checkout') + msg = QtWidgets.QMessageBox(parent=self) + msg.setIcon(QtWidgets.QMessageBox.Critical) + msg.setText('Failed to open file as either an active or passive ' + 'checkout. The file may be corrupted or malformed.') + msg.setWindowTitle('Could not open file') + msg.exec_() + return self._new_tab(data=data, filename=filename) def _new_tab( diff --git a/docs/source/upcoming_release_notes/213-mnt_bug_misc_fixes.rst b/docs/source/upcoming_release_notes/213-mnt_bug_misc_fixes.rst new file mode 100644 index 00000000..10590d8a --- /dev/null +++ b/docs/source/upcoming_release_notes/213-mnt_bug_misc_fixes.rst @@ -0,0 +1,27 @@ +213 mnt_bug_misc_fixes +###################### + +API Breaks +---------- +- N/A + +Features +-------- +- N/A + +Bugfixes +-------- +- `RangeWidget`'s visualizations update a bit more frequently, and also the label text actually updates. Closes #212 +- Adds a menu option to open the welcome tab, since people like it. Closes #201 +- Properly shows an error message box when a file can't be opened. Closes #202 +- Removes child `AtefItem` from a ProcedureStep when it's changed from the specific-step-combobox. Closes #195 +- Allow tolerances to be `None` in `Equals` comparison. Modifies the line-edit setup to allow null values (`''`, `None`) when casting the line edit value. Closes #128 + + +Maintenance +----------- +- N/A + +Contributors +------------ +- tangkong