Skip to content

Commit

Permalink
Fix project marked dirty when model expression unchanged
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfokkema committed Feb 27, 2024
1 parent 56a5536 commit 02a079e
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/tailor/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,12 @@ def load_project(self, filename):
# remember filename for subsequent call to "Save"
self._set_project_path(filename)
self.update_recent_files(filename)
# rebuild UI on all tabs
current_idx = self.ui.tabWidget.currentIndex()
for idx in range(self.ui.tabWidget.count()):
self.ui.tabWidget.setCurrentIndex(idx)
self.ui.tabWidget.setCurrentIndex(current_idx)
# mark project as not dirty (clean)
self.mark_project_dirty(False)

def export_csv(self):
Expand Down
8 changes: 7 additions & 1 deletion src/tailor/plot_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def get_limits_from_data(self, padding=0.05) -> tuple[float]:

return xmin, xmax, ymin, ymax

def update_model_expression(self, expression: str) -> None:
def update_model_expression(self, expression: str) -> bool:
"""Update the model expression.
Update the stored (transformed) model expression independent of column
Expand All @@ -269,6 +269,9 @@ def update_model_expression(self, expression: str) -> None:
Args:
expression (str): the model expression.
Returns:
True if the expression is successfully updated, False otherwise.
"""
# remove whitespace after newlines to prevent indentation errors
expression = re.sub(r"\n\s*", "\n", expression)
Expand All @@ -281,6 +284,7 @@ def update_model_expression(self, expression: str) -> None:
self._model_expression = expression
self._model = None
self.best_fit = None
return True
else:
if self._model_expression != transformed:
self._model_expression = transformed
Expand All @@ -294,6 +298,8 @@ def update_model_expression(self, expression: str) -> None:
else:
self.update_model_parameters()
self.best_fit = None
return True
return False

def is_model_valid(self) -> bool:
"""Return if the model expression is a valid model.
Expand Down
5 changes: 3 additions & 2 deletions src/tailor/plot_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,13 @@ def get_adjusted_limits(self):
def update_model_expression(self):
"""Update the model expression and related UI."""
expression = self.ui.model_func.toPlainText()
self.model.update_model_expression(expression)
is_updated = self.model.update_model_expression(expression)
self.update_expression_border()
self.update_params_ui()
self.plot_initial_model()
self.plot_best_fit()
self.main_window.mark_project_dirty()
if is_updated:
self.main_window.mark_project_dirty()

def update_expression_border(self) -> None:
"""Update border of the model expression widget.
Expand Down
12 changes: 10 additions & 2 deletions tests/test_plot_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,9 @@ def test_update_model_expression(
model.data_model.get_column_name.return_value = col_names[x_col]
model.x_col = x_col

model.update_model_expression(expression)
is_updated = model.update_model_expression(expression)

assert is_updated is True
model.data_model.get_column_name.assert_called_with(x_col)
assert model._model_expression == transformed
assert isinstance(model._model, lmfit.models.ExpressionModel)
Expand All @@ -334,9 +335,16 @@ def test_update_model_expression_keeps_fit_if_no_changes(
bare_bones_data.data_model.get_column_name.return_value = "x"
bare_bones_data.best_fit = sentinel.fit

bare_bones_data.update_model_expression("a*x+b")
is_updated = bare_bones_data.update_model_expression("a*x+b")
assert is_updated is False
assert bare_bones_data.best_fit is sentinel.fit

def test_update_model_expression_returns_True_if_expr_is_broken(
self, bare_bones_data: PlotModel
):
is_updated = bare_bones_data.update_model_expression("a*x+")
assert is_updated is True

@pytest.mark.parametrize(
"expression, transformed",
[("x + (2 * ", "x + (2 * "), ("a * y + b", "a * y + b")],
Expand Down

0 comments on commit 02a079e

Please sign in to comment.