From a0d09692d74413b0d4b082a58fc9c9ee65a4b835 Mon Sep 17 00:00:00 2001 From: Rebecca Breu Date: Tue, 28 Nov 2023 21:23:24 +0100 Subject: [PATCH] Make text changes undoable --- CHANGELOG.rst | 1 + beeref/commands.py | 16 +++++++++++++++- beeref/items.py | 3 +++ tests/test_commands.py | 9 +++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0f45a34..beccd35 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,6 +21,7 @@ Changed * "Save as" will now open pre-select the folder of the currently opened file * "Save" and "Save as" are now inactive when the scene is empty +* Editing of text items will now be undoable after leaving edit mode Fixed diff --git a/beeref/commands.py b/beeref/commands.py index 8a232f8..1f7cd9f 100644 --- a/beeref/commands.py +++ b/beeref/commands.py @@ -50,7 +50,6 @@ class InsertItems(QtGui.QUndoCommand): class DeleteItems(QtGui.QUndoCommand): - def __init__(self, scene, items): super().__init__('Delete items') self.scene = scene @@ -308,3 +307,18 @@ class CropItem(QtGui.QUndoCommand): def undo(self): self.item.crop = self.old_crop + + +class ChangeText(QtGui.QUndoCommand): + + def __init__(self, item, new_text, old_text): + super().__init__('Change text') + self.item = item + self.new_text = new_text + self.old_text = old_text + + def redo(self): + self.item.setPlainText(self.new_text) + + def undo(self): + self.item.setPlainText(self.old_text) diff --git a/beeref/items.py b/beeref/items.py index 9b692df..fe021ae 100644 --- a/beeref/items.py +++ b/beeref/items.py @@ -542,6 +542,7 @@ class BeeTextItem(BeeItemMixin, QtWidgets.QGraphicsTextItem): def enter_edit_mode(self): logger.debug(f'Entering edit mode on {self}') self.edit_mode = True + self.old_text = self.toPlainText() self.setTextInteractionFlags( Qt.TextInteractionFlag.TextEditorInteraction) self.scene().edit_item = self @@ -552,6 +553,8 @@ class BeeTextItem(BeeItemMixin, QtWidgets.QGraphicsTextItem): # reset selection: self.setTextCursor(QtGui.QTextCursor(self.document())) self.setTextInteractionFlags(Qt.TextInteractionFlag.NoTextInteraction) + self.scene().undo_stack.push( + commands.ChangeText(self, self.toPlainText(), self.old_text)) self.scene().edit_item = None def has_selection_handles(self): diff --git a/tests/test_commands.py b/tests/test_commands.py index 8e67104..7f059d3 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -474,3 +474,12 @@ def test_crop_item(item): command.undo() assert item.crop == QtCore.QRectF(0, 0, 100, 80) assert item.pos() == QtCore.QPointF(0, 0) + + +def test_change_text(): + item = BeeTextItem('foo') + command = commands.ChangeText(item, 'bar', 'foo') + command.redo() + assert item.toPlainText() == 'bar' + command.undo() + assert item.toPlainText() == 'foo'