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