Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d1f1b73
Enhance ProofModel by group expansion functionality.
axif0 Feb 14, 2026
1d5f5b2
Fix mypy type errors and enhance type hints in proof and rewrite modu…
axif0 Feb 16, 2026
3323321
feat: Allow selection of individual sub-steps within grouped proof st…
axif0 Feb 17, 2026
84ef377
Merge branch 'master' of https://github.com/axif0/zxlive into copy
axif0 Feb 17, 2026
0665d4a
Implement sub-step renaming with an inline editor
axif0 Feb 18, 2026
bd7e8ec
Refactor imports and clean up whitespace in proof, rewrite_action, re…
axif0 Feb 23, 2026
003215f
Refactor proof step rendering to differentiate between hovering over …
axif0 Feb 25, 2026
070fb64
add missing `end line` at the end
axif0 Feb 25, 2026
b40ea25
feat: Introduce functionality to modify and undo/redo changes for ind…
axif0 Feb 25, 2026
e334dcf
removed blank space from proof
axif0 Feb 25, 2026
2979bf1
Fixing line alignment, sub_circle colour and size.
boldar99 Feb 26, 2026
4787530
Merge branch 'master' of https://github.com/axif0/zxlive into copy
axif0 Feb 26, 2026
541f9e4
sub-step selection bugs and modernize type hints
axif0 Feb 26, 2026
3581d2e
refactor: Reorder sub-step drawing in `ProofStepDelegate` to ensure h…
axif0 Feb 26, 2026
693c806
feat: Implement rewriting from within a grouped sub-step, including t…
axif0 Feb 27, 2026
b8d129e
extract click and hover target detection logic into dedicated helper …
axif0 Feb 28, 2026
0a51d6f
undo type hint changes of mine
axif0 Mar 1, 2026
ff0467b
exact match with previous commit.
axif0 Mar 1, 2026
c3fecdc
Merge branch 'master' of https://github.com/zxcalc/zxlive into copy
axif0 Mar 5, 2026
e438f4a
refactor code implementation ffor proofModel
axif0 Mar 5, 2026
284b5ac
fix lint error
axif0 Mar 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 56 additions & 11 deletions zxlive/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,14 @@ class AddRewriteStep(UpdateGraph):
The rewrite is inserted after the currently selected step. In particular, it
replaces all rewrites that were previously after the current selection.
"""
step_view: QListView
step_view: ProofStepView
name: str
diff: Optional[GraphDiff] = None

_old_selected: Optional[int] = field(default=None, init=False)
_old_steps: list[tuple[Rewrite, GraphT]] = field(default_factory=list, init=False)
_old_group_rewrite: Optional[Rewrite] = field(default=None, init=False)
_old_sub_idx: int = field(default=-1, init=False)

@property
def proof_model(self) -> ProofModel:
Expand All @@ -459,11 +461,32 @@ def proof_model(self) -> ProofModel:
return model

def redo(self) -> None:
# Remove steps from the proof model until we're at the currently selected step
self._old_selected = int(self.step_view.currentIndex().row())
self._old_steps = []
for _ in range(self.proof_model.rowCount() - self._old_selected - 1):
self._old_steps.append(self.proof_model.pop_rewrite())
self._old_group_rewrite = None
self._old_sub_idx = -1

current = self.step_view.currentIndex()

# Check if the user is rewriting from inside a grouped sub-step.
if current.parent().isValid() and isinstance(self.step_view, ProofStepView):
parent_row = current.parent().row()
group_step_idx = parent_row - 1
sub_idx = current.row()
self._old_selected = parent_row
self._old_sub_idx = sub_idx

# 1. Pop all main steps that come AFTER the grouped step.
steps_after_group = self.proof_model.rowCount() - 1 - parent_row
for _ in range(steps_after_group):
self._old_steps.append(self.proof_model.pop_rewrite())

# 2. Truncate the grouped step: keep only sub-steps 0..sub_idx.
self._old_group_rewrite = self.proof_model.truncate_group(group_step_idx, sub_idx + 1)
else:
# Normal case: remove all steps after the currently selected step.
self._old_selected = int(current.row())
for _ in range(self.proof_model.rowCount() - self._old_selected - 1):
self._old_steps.append(self.proof_model.pop_rewrite())

self.proof_model.add_rewrite(Rewrite(self.name, self.name, self.new_g))

Expand All @@ -480,16 +503,33 @@ def undo(self) -> None:
self.proof_model.pop_rewrite()
self.step_view.selectionModel().blockSignals(False)

# Add back steps that were previously removed
if self._old_group_rewrite is not None:
# Restore the original grouped step (undo truncation/ungrouping).
assert self._old_selected is not None
group_step_idx = self._old_selected - 1
self.proof_model.restore_group(group_step_idx, self._old_group_rewrite)

# Restore main steps that were popped (LIFO order, restore in reverse).
for rewrite, graph in reversed(self._old_steps):
self.proof_model.add_rewrite(rewrite)

# Select the previously selected step
assert self._old_selected is not None
idx = self.step_view.model().index(self._old_selected, 0, QModelIndex())
self.step_view.selectionModel().blockSignals(True)
self.step_view.setCurrentIndex(idx)
self.step_view.selectionModel().blockSignals(False)
if (self._old_group_rewrite is not None
and self._old_sub_idx >= 0
and isinstance(self.step_view, ProofStepView)):
# Navigate back into the restored group's sub-step.
parent_idx = self.step_view.model().index(self._old_selected, 0)
self.step_view.expand(parent_idx)
child_idx = self.step_view.model().index(self._old_sub_idx, 0, parent_idx)
self.step_view.selectionModel().blockSignals(True)
self.step_view.setCurrentIndex(child_idx)
self.step_view.selectionModel().blockSignals(False)
else:
idx = self.step_view.model().index(self._old_selected, 0, QModelIndex())
self.step_view.selectionModel().blockSignals(True)
self.step_view.setCurrentIndex(idx)
self.step_view.selectionModel().blockSignals(False)
super().undo()


Expand All @@ -513,10 +553,15 @@ class UngroupRewriteSteps(BaseCommand):
step_view: ProofStepView
group_index: int

_group_size: int = field(default=0, init=False)

def redo(self) -> None:
grouped = self.step_view.model().steps[self.group_index].grouped_rewrites
assert grouped is not None
self._group_size = len(grouped)
self.step_view.model().ungroup_steps(self.group_index)
self.step_view.move_to_step(self.group_index + 1)

def undo(self) -> None:
self.step_view.model().group_steps(self.group_index, self.group_index + 1)
self.step_view.model().group_steps(self.group_index, self.group_index + self._group_size - 1)
self.step_view.move_to_step(self.group_index + 1)
Loading
Loading