Skip to content

Commit 5079557

Browse files
committed
Make values redoable
1 parent 4af69ec commit 5079557

2 files changed

Lines changed: 46 additions & 24 deletions

File tree

src/petab_gui/commands.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,46 @@ def _apply(self, src, dst):
318318
self.model.dataChanged.emit(
319319
self.model_index, self.model_index, [Qt.DisplayRole]
320320
)
321+
322+
323+
class RenameValueCommand(QUndoCommand):
324+
"""Command to rename values in specified columns."""
325+
326+
def __init__(
327+
self, model, old_id: str, new_id: str, column_names: str | list[str]
328+
):
329+
super().__init__(f"Rename value {old_id}{new_id}")
330+
self.model = model
331+
self.old_id = old_id
332+
self.new_id = new_id
333+
self.column_names = (
334+
column_names if isinstance(column_names, list) else [column_names]
335+
)
336+
self.changes = {} # {(row_idx, col_name): (old_val, new_val)}
337+
338+
df = self.model._data_frame
339+
for col_name in self.column_names:
340+
mask = df[col_name].eq(self.old_id)
341+
for row_idx in df.index[mask]:
342+
self.changes[(row_idx, col_name)] = (self.old_id, self.new_id)
343+
344+
def redo(self):
345+
self._apply_changes(use_new=True)
346+
347+
def undo(self):
348+
self._apply_changes(use_new=False)
349+
350+
def _apply_changes(self, use_new: bool):
351+
df = self.model._data_frame
352+
for (row_idx, col_name), (old_val, new_val) in self.changes.items():
353+
df.at[row_idx, col_name] = new_val if use_new else old_val
354+
355+
if self.changes:
356+
rows = [df.index.get_loc(row) for (row, _) in self.changes]
357+
cols = [df.columns.get_loc(col) + 1 for (_, col) in self.changes]
358+
top_left = self.model.index(min(rows), min(cols))
359+
bottom_right = self.model.index(max(rows), max(cols))
360+
self.model.dataChanged.emit(
361+
top_left, bottom_right, [Qt.DisplayRole, Qt.EditRole]
362+
)
363+
self.model.something_changed.emit(True)

src/petab_gui/controllers/table_controllers.py

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
)
1919

2020
from ..C import COLUMN, INDEX
21+
from ..commands import RenameValueCommand
2122
from ..models.pandas_table_model import (
2223
PandasTableFilterProxy,
2324
PandasTableModel,
@@ -604,30 +605,8 @@ def rename_value(
604605
column_names:
605606
The column or list of columns in which the id should be changed.
606607
"""
607-
if not isinstance(column_names, list):
608-
column_names = [column_names]
609-
610-
for col_name in column_names:
611-
# Find occurrences
612-
mask = self.model._data_frame[col_name].eq(old_id)
613-
if not mask.any():
614-
continue
615-
616-
self.model._data_frame.loc[mask, col_name] = new_id
617-
first_row, last_row = (
618-
mask.idxmax(),
619-
mask[::-1].idxmax(),
620-
)
621-
top_left = self.model.index(first_row, 1)
622-
bottom_right = self.model.index(
623-
last_row, self.model.columnCount() - 1
624-
)
625-
self.model.dataChanged.emit(
626-
top_left, bottom_right, [Qt.DisplayRole, Qt.EditRole]
627-
)
628-
629-
# Emit change signal
630-
self.model.something_changed.emit(True)
608+
command = RenameValueCommand(self.model, old_id, new_id, column_names)
609+
self.undo_stack.push(command)
631610

632611

633612
class MeasurementController(TableController):

0 commit comments

Comments
 (0)