groovy.ui.text.TextUndoManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of groovy-all Show documentation
Show all versions of groovy-all Show documentation
Groovy: A powerful, dynamic language for the JVM
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package groovy.ui.text;
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
import javax.swing.event.UndoableEditEvent;
import javax.swing.undo.CompoundEdit;
import javax.swing.undo.UndoManager;
import javax.swing.undo.UndoableEdit;
/**
* To use this, simply drop this as an UndoableEditListener into your document,
* and then create actions to call undo/redo as needed (checking can undo/redo
* first, of course).
*
* @author Evan "Hippy" Slatis
*/
public class TextUndoManager extends UndoManager {
private SwingPropertyChangeSupport propChangeSupport =
new SwingPropertyChangeSupport(this);
private StructuredEdit compoundEdit = new StructuredEdit();
private long firstModified;
private UndoableEdit modificationMarker = editToBeUndone();
/**
* Creates a new instance of TextUndoManager.
*/
public TextUndoManager() {
}
public void addPropertyChangeListener(PropertyChangeListener pcl) {
propChangeSupport.addPropertyChangeListener(pcl);
}
public void die() {
boolean undoable = canUndo();
super.die();
firePropertyChangeEvent(UndoManager.UndoName, undoable, canUndo());
}
public void discardAllEdits() {
boolean undoable = canUndo();
boolean redoable = canRedo();
boolean changed = hasChanged();
super.discardAllEdits();
modificationMarker = editToBeUndone();
firePropertyChangeEvent(UndoManager.UndoName, undoable, canUndo());
firePropertyChangeEvent(UndoManager.UndoName, redoable, canRedo());
}
protected void firePropertyChangeEvent(String name,
boolean oldValue,
boolean newValue) {
propChangeSupport.firePropertyChange(name, oldValue, newValue);
}
public boolean hasChanged() {
return modificationMarker != editToBeUndone();
}
public void redo() throws javax.swing.undo.CannotRedoException {
compoundEdit.end();
if (firstModified == 0) {
firstModified = ((StructuredEdit) editToBeRedone()).editedTime();
}
boolean undoable = canUndo();
boolean changed = hasChanged();
super.redo();
firePropertyChangeEvent(UndoManager.UndoName, undoable, canUndo());
}
protected void redoTo(UndoableEdit edit) {
compoundEdit.end();
if (firstModified == 0) {
firstModified = ((StructuredEdit) editToBeRedone()).editedTime();
}
boolean undoable = canUndo();
boolean changed = hasChanged();
super.redoTo(edit);
firePropertyChangeEvent(UndoManager.UndoName, undoable, canUndo());
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
propChangeSupport.removePropertyChangeListener(pcl);
}
public void reset() {
boolean changed = modificationMarker != editToBeUndone();
if (changed) {
modificationMarker = editToBeUndone();
}
}
protected void trimEdits(int from, int to) {
boolean undoable = canUndo();
boolean redoable = canRedo();
boolean changed = hasChanged();
super.trimEdits(from, to);
firePropertyChangeEvent(UndoManager.UndoName, undoable, canUndo());
firePropertyChangeEvent(UndoManager.RedoName, redoable, canRedo());
}
public void undo() throws javax.swing.undo.CannotUndoException {
compoundEdit.end();
UndoableEdit edit = editToBeUndone();
if (((StructuredEdit) editToBeUndone()).editedTime() ==
firstModified) {
firstModified = 0;
} else if (firstModified == 0) {
firstModified = ((StructuredEdit) editToBeUndone()).editedTime();
}
boolean redoable = canRedo();
boolean changed = hasChanged();
super.undo();
firePropertyChangeEvent(UndoManager.RedoName, redoable, canRedo());
}
public void undoableEditHappened(UndoableEditEvent uee) {
UndoableEdit edit = uee.getEdit();
boolean undoable = canUndo();
long editTime = System.currentTimeMillis();
if (firstModified == 0 ||
editTime - compoundEdit.editedTime() > 700) {
compoundEdit.end();
compoundEdit = new StructuredEdit();
}
compoundEdit.addEdit(edit);
firstModified = firstModified == 0 ?
compoundEdit.editedTime() : firstModified;
if (lastEdit() != compoundEdit) {
boolean changed = hasChanged();
addEdit(compoundEdit);
firePropertyChangeEvent(UndoManager.UndoName, undoable, canUndo());
}
}
private class StructuredEdit extends CompoundEdit {
private long editedTime;
public boolean addEdit(UndoableEdit edit) {
boolean result = super.addEdit(edit);
if (result && editedTime == 0) {
editedTime = System.currentTimeMillis();
}
return result;
}
public boolean canUndo() {
return edits.size() > 0;
}
protected long editedTime() {
return editedTime;
}
public boolean isInProgress() {
return false;
}
}
}