v1.8.12: fix Ctrl+Z undo — manual implementation for tk.Entry
tk.Entry has no built-in undo (unlike tk.Text), so _entry.config(undo=True) crashed. Replaced with custom entry_undo.py that tracks history manually and binds Ctrl+Z/Ctrl+Y (+ Russian layout support). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
54
gui/widgets/entry_undo.py
Normal file
54
gui/widgets/entry_undo.py
Normal file
@@ -0,0 +1,54 @@
|
||||
"""
|
||||
Ctrl+Z / Ctrl+Y undo/redo for CTkEntry widgets.
|
||||
tk.Entry has no built-in undo, so we track history manually.
|
||||
"""
|
||||
|
||||
|
||||
def enable_undo(ctk_entry):
|
||||
"""Add Ctrl+Z undo and Ctrl+Y redo to a CTkEntry widget."""
|
||||
entry = ctk_entry._entry
|
||||
history = [entry.get()]
|
||||
redo_stack = []
|
||||
_recording = [True]
|
||||
|
||||
def _snapshot(*_args):
|
||||
if not _recording[0]:
|
||||
return
|
||||
val = entry.get()
|
||||
if not history or history[-1] != val:
|
||||
history.append(val)
|
||||
redo_stack.clear()
|
||||
# Cap history size
|
||||
if len(history) > 200:
|
||||
del history[:100]
|
||||
|
||||
def _undo(event):
|
||||
if len(history) > 1:
|
||||
redo_stack.append(history.pop())
|
||||
_recording[0] = False
|
||||
entry.delete(0, "end")
|
||||
entry.insert(0, history[-1])
|
||||
_recording[0] = True
|
||||
elif history:
|
||||
redo_stack.append(history.pop())
|
||||
_recording[0] = False
|
||||
entry.delete(0, "end")
|
||||
_recording[0] = True
|
||||
return "break"
|
||||
|
||||
def _redo(event):
|
||||
if redo_stack:
|
||||
val = redo_stack.pop()
|
||||
history.append(val)
|
||||
_recording[0] = False
|
||||
entry.delete(0, "end")
|
||||
entry.insert(0, val)
|
||||
_recording[0] = True
|
||||
return "break"
|
||||
|
||||
entry.bind("<KeyRelease>", _snapshot, add="+")
|
||||
entry.bind("<Control-z>", _undo)
|
||||
entry.bind("<Control-y>", _redo)
|
||||
# Support Russian keyboard layout (Cyrillic keycodes)
|
||||
entry.bind("<Control-\u044f>", _undo) # Ctrl+Я (z position on Russian layout)
|
||||
entry.bind("<Control-\u043d>", _redo) # Ctrl+Н (y position on Russian layout)
|
||||
Reference in New Issue
Block a user