Mercurial Hosting > luan
changeset 1908:1d60e0ac3b97
undo transactions
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 15 Apr 2025 21:51:41 -0600 |
parents | cbd2f1b8ff2c |
children | 474f7ab2d1c2 |
files | src/luan/modules/swing/Document.luan src/luan/modules/swing/TextAreaLuan.java src/luan/modules/swing/Text_area.luan src/luan/modules/swing/Text_component.luan src/luan/modules/swing/UndoManagerLuan.java |
diffstat | 5 files changed, 81 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/modules/swing/Document.luan Tue Apr 15 20:08:46 2025 -0600 +++ b/src/luan/modules/swing/Document.luan Tue Apr 15 21:51:41 2025 -0600 @@ -21,6 +21,14 @@ document.is_unedited = undo.isUnedited document.set_unedited = undo.setUnedited document.clear_unedited = undo.clearUnedited + function document.run_in_transaction(fn) + undo.beginTransaction() + try + return fn() + finally + undo.endTransaction() + end + end return document end
--- a/src/luan/modules/swing/TextAreaLuan.java Tue Apr 15 20:08:46 2025 -0600 +++ b/src/luan/modules/swing/TextAreaLuan.java Tue Apr 15 21:51:41 2025 -0600 @@ -11,6 +11,7 @@ import javax.swing.UIManager; import javax.swing.Timer; import javax.swing.text.DefaultCaret; +import javax.swing.text.AbstractDocument; import javax.swing.text.BadLocationException; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; @@ -95,4 +96,38 @@ g.drawString( symbol, r.x, r.y + ascent ); } } + + private UndoManagerLuan getUndoManagerLuan() { + return (UndoManagerLuan)getDocument().getProperty("undo"); + } + + @Override public void paste() { + UndoManagerLuan undo = getUndoManagerLuan(); + undo.beginTransaction(); + try { + super.paste(); + } finally { + undo.endTransaction(); + } + } + + @Override public void setText(String t) { + UndoManagerLuan undo = getUndoManagerLuan(); + undo.beginTransaction(); + try { + super.setText(t); + } finally { + undo.endTransaction(); + } + } + + public void replace(int offset, int length, String text) throws BadLocationException { + UndoManagerLuan undo = getUndoManagerLuan(); + undo.beginTransaction(); + try { + ((AbstractDocument)getDocument()).replace(offset,length,text,null); + } finally { + undo.endTransaction(); + } + } }
--- a/src/luan/modules/swing/Text_area.luan Tue Apr 15 20:08:46 2025 -0600 +++ b/src/luan/modules/swing/Text_area.luan Tue Apr 15 21:51:41 2025 -0600 @@ -99,7 +99,7 @@ return jtext_area.insert(text,pos-1) end function text_area.replace(start_pos,length,text) - return jtext_area.getDocument().replace(start_pos-1,length,text) + return jtext_area.replace(start_pos-1,length,text) end set_metatable(text_area,mt) return text_area
--- a/src/luan/modules/swing/Text_component.luan Tue Apr 15 20:08:46 2025 -0600 +++ b/src/luan/modules/swing/Text_component.luan Tue Apr 15 21:51:41 2025 -0600 @@ -52,12 +52,14 @@ local document = jcomponent.getDocument() local start = jcomponent.getSelectionStart() local end_ = jcomponent.getSelectionEnd() - if end_ > start then - document.remove( start, end_ - start ) - end - if #value > 0 then - document.insertString( start, value, nil ) - end + component._document.run_in_transaction(function() + if end_ > start then + document.remove( start, end_ - start ) + end + if #value > 0 then + document.insertString( start, value, nil ) + end + end) jcomponent.select( start, start + #value ) return end
--- a/src/luan/modules/swing/UndoManagerLuan.java Tue Apr 15 20:08:46 2025 -0600 +++ b/src/luan/modules/swing/UndoManagerLuan.java Tue Apr 15 21:51:41 2025 -0600 @@ -1,10 +1,13 @@ package luan.modules.swing; import java.util.WeakHashMap; +import java.util.List; +import java.util.ArrayList; import javax.swing.event.UndoableEditListener; import javax.swing.event.UndoableEditEvent; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; +import javax.swing.undo.CompoundEdit; import javax.swing.undo.CannotUndoException; import javax.swing.undo.CannotRedoException; import goodjava.util.GoodUtils; @@ -22,6 +25,7 @@ private final WeakHashMap<LuanFunction,Boolean> map = new WeakHashMap<LuanFunction,Boolean>(); private final Luan luan; private UndoableEdit unedited = null; + private final List<CompoundEdit> transactions = new ArrayList<CompoundEdit>(); public UndoManagerLuan(Luan luan) { this.luan = luan; @@ -38,8 +42,13 @@ } @Override public void undoableEditHappened(UndoableEditEvent event) { - super.undoableEditHappened(event); - notifyListeners(); + int n = transactions.size(); + if( n == 0 ) { + super.undoableEditHappened(event); + notifyListeners(); + } else { + if( !transactions.get(n-1).addEdit( event.getEdit() ) ) throw new RuntimeException(); + } } @Override public void undo() throws CannotUndoException { @@ -70,4 +79,22 @@ unedited = null; notifyListeners(); } + + public void beginTransaction() { + //logger.info("beginTransaction"); + transactions.add(new CompoundEdit()); + } + + public void endTransaction() { + //logger.info("endTransaction"); + int n = transactions.size(); + CompoundEdit ce = transactions.remove(n-1); + ce.end(); + if( n == 1 ) { + if( !addEdit(ce) ) throw new RuntimeException(); + } else { + if( !transactions.get(n-2).addEdit(ce) ) throw new RuntimeException(); + } + notifyListeners(); + } }