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;