You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by no...@apache.org on 2011/01/21 12:59:35 UTC
svn commit: r1061773 - in /pivot/trunk/wtk/src/org/apache/pivot/wtk:
TextPane.java skin/TextPaneSkin.java
Author: noelgrandin
Date: Fri Jan 21 11:59:35 2011
New Revision: 1061773
URL: http://svn.apache.org/viewvc?rev=1061773&view=rev
Log:
PIVOT-698 Support undo in TextPane
Modified:
pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java
pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextPaneSkin.java
Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java?rev=1061773&r1=1061772&r2=1061773&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java Fri Jan 21 11:59:35 2011
@@ -21,6 +21,7 @@ import java.io.StringReader;
import java.io.StringWriter;
import org.apache.pivot.beans.DefaultProperty;
+import org.apache.pivot.collections.LinkedList;
import org.apache.pivot.collections.Sequence;
import org.apache.pivot.util.ListenerList;
import org.apache.pivot.wtk.media.Image;
@@ -106,6 +107,42 @@ public class TextPane extends Container
public Bounds getCharacterBounds(int offset);
}
+ private interface Edit {
+ public void undo();
+ }
+
+ private class RangeRemovedEdit implements Edit {
+ private final Node node;
+ private final int offset;
+ private final Node range;
+
+ public RangeRemovedEdit(Node node, int offset, int characterCount) {
+ this.node = node;
+ this.offset = offset;
+ this.range = node.getRange(offset, characterCount);
+ }
+
+ public void undo() {
+ node.insertRange(range, offset);
+ }
+ }
+
+ private class RangeInsertedEdit implements Edit {
+ private final Node node;
+ private final int offset;
+ private final int characterCount;
+
+ public RangeInsertedEdit(Node node, int offset, int characterCount) {
+ this.node = node;
+ this.offset = offset;
+ this.characterCount = characterCount;
+ }
+
+ public void undo() {
+ node.removeRange(offset, characterCount);
+ }
+ }
+
private static class TextPaneListenerList extends ListenerList<TextPaneListener>
implements TextPaneListener {
@Override
@@ -157,6 +194,7 @@ public class TextPane extends Container
private int selectionLength = 0;
private boolean editable = true;
+ private boolean undoingHistory = false;
private ComponentNodeListener componentNodeListener = new ComponentNodeListener() {
@Override
@@ -167,15 +205,7 @@ public class TextPane extends Container
}
};
- private NodeListener documentListener = new NodeListener() {
- @Override
- public void parentChanged(Node node, Element previousParent) {
- }
-
- @Override
- public void offsetChanged(Node node, int previousOffset) {
- }
-
+ private NodeListener documentListener = new NodeListener.Adapter() {
@Override
public void rangeInserted(Node node, int offset, int characterCount) {
if (selectionStart + selectionLength > offset) {
@@ -186,10 +216,16 @@ public class TextPane extends Container
}
}
+ if (!undoingHistory) {
+ addHistoryItem(new RangeInsertedEdit(node, offset, characterCount));
+ }
+
textPaneCharacterListeners.charactersInserted(TextPane.this, offset, characterCount);
}
+ @Override
public void nodesRemoved(Node node, Sequence<Node> removed, int offset) {
+
for (int i = 0; i < removed.getLength(); i++) {
Node descendant = removed.get(i);
if (descendant instanceof ComponentNode) {
@@ -228,14 +264,22 @@ public class TextPane extends Container
}
}
+ if (!undoingHistory) {
+ addHistoryItem(new RangeRemovedEdit(node, offset, characterCount));
+ }
+
textPaneCharacterListeners.charactersRemoved(TextPane.this, offset, characterCount);
}
};
+ private LinkedList<Edit> editHistory = new LinkedList<Edit>();
+
private TextPaneListenerList textPaneListeners = new TextPaneListenerList();
private TextPaneCharacterListenerList textPaneCharacterListeners = new TextPaneCharacterListenerList();
private TextPaneSelectionListenerList textPaneSelectionListeners = new TextPaneSelectionListenerList();
+ private static final int MAXIMUM_EDIT_HISTORY_LENGTH = 30;
+
public TextPane() {
installSkin(TextPane.class);
}
@@ -278,6 +322,9 @@ public class TextPane extends Container
addComponentNodes(document);
}
+ // Clear the edit history
+ editHistory.clear();
+
this.document = document;
selectionStart = 0;
@@ -578,13 +625,28 @@ public class TextPane extends Container
}
public void undo() {
- // TODO
+ int n = editHistory.getLength();
+ if (n > 0) {
+ undoingHistory = true;
+ Edit edit = editHistory.remove(n - 1, 1).get(0);
+ edit.undo();
+ undoingHistory = false;
+ }
+ }
+
+ private void addHistoryItem(Edit edit) {
+ editHistory.add(edit);
+
+ if (editHistory.getLength() > MAXIMUM_EDIT_HISTORY_LENGTH) {
+ editHistory.remove(0, 1);
+ }
}
public void redo() {
// TODO
}
+
/**
* Returns the starting index of the selection.
*
Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextPaneSkin.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextPaneSkin.java?rev=1061773&r1=1061772&r2=1061773&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextPaneSkin.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextPaneSkin.java Fri Jan 21 11:59:35 2011
@@ -950,9 +950,9 @@ public class TextPaneSkin extends Contai
} else if (keyCode == Keyboard.KeyCode.Z
&& textPane.isEditable()) {
if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
- textPane.undo();
- } else {
textPane.redo();
+ } else {
+ textPane.undo();
}
consumed = true;