remove positions when range is deleted
Change-Id: Ib8d295a7f1dc1b620812646f4a2f808c0ae6bc1f
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java
index bcb6406..9a92e9d 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Florian Thienel - initial API and implementation
*******************************************************************************/
@@ -172,20 +172,6 @@
}
@Test
- public void shouldMovePositionsWithinRemovedRangeToRangeStart() throws Exception {
- content.insertText(0, "Hello New World");
- final IPosition nPosition = content.createPosition(6);
- final IPosition ePosition = content.createPosition(7);
- final IPosition wPosition = content.createPosition(8);
-
- content.remove(new ContentRange(6, 8));
-
- assertEquals(6, nPosition.getOffset());
- assertEquals(6, ePosition.getOffset());
- assertEquals(6, wPosition.getOffset());
- }
-
- @Test
public void canRemovePosition() throws Exception {
content.insertTagMarker(0);
content.insertTagMarker(0);
@@ -231,4 +217,23 @@
assertEquals(content.getRawText().charAt(i), content.charAt(i));
}
}
+
+ @Test
+ public void whenDeletingRange_shouldInvalidatePosistionsInRange() throws Exception {
+ content.insertTagMarker(0);
+ content.insertText(0, "Hello");
+ content.insertTagMarker(0);
+ final IPosition positionBefore = content.createPosition(0);
+ final IPosition firstDeletedPosition = content.createPosition(1);
+ final IPosition lastDeletedPosition = content.createPosition(5);
+ final IPosition positionAfter = content.createPosition(6);
+
+ content.remove(new ContentRange(1, 5));
+
+ assertTrue("before", positionBefore.isValid());
+ assertFalse("first deleted", firstDeletedPosition.isValid());
+ assertFalse("last deleted", lastDeletedPosition.isValid());
+ assertTrue("after", positionAfter.isValid());
+ }
+
}
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/GapContentTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/GapContentTest.java
index 9ef1ea0..6fd6d6e 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/GapContentTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/GapContentTest.java
@@ -4,13 +4,14 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* John Krasnay - initial API and implementation
*******************************************************************************/
package org.eclipse.vex.core.internal.dom;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
@@ -55,6 +56,22 @@
}
@Test
+ public void whenDeletingRange_shouldRemovePosistionsInRange() throws Exception {
+ final GapContent content = new GapContent(10);
+ content.insertTagMarker(0);
+ content.insertText(0, "Hello");
+ content.insertTagMarker(0);
+ content.createPosition(0);
+ content.createPosition(1);
+ content.createPosition(5);
+ content.createPosition(6);
+
+ content.remove(new ContentRange(1, 5));
+
+ assertEquals(2, content.getPositionCount());
+ }
+
+ @Test
public void testGapContent() throws Exception {
//
// a b (gap) c d
@@ -133,7 +150,7 @@
// a b x (gap) y c d
// | | | | | | |
// 0 1 2 3 4 5 6
- //
+ //
content.insertText(2, "y");
assertEquals(5, content.length());
content.insertText(2, "x");
@@ -156,8 +173,10 @@
assertEquals(0, pa.getOffset());
assertEquals(1, pb.getOffset());
- assertEquals(2, px.getOffset());
- assertEquals(2, py.getOffset());
+
+ assertFalse(px.isValid());
+ assertFalse(py.isValid());
+
assertEquals(2, pc.getOffset());
assertEquals(3, pd.getOffset());
assertEquals(4, pe.getOffset());
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
index 3e54a96..9ed6173 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
@@ -102,8 +102,7 @@
widget.setDocument(createDocument(STRUCTURE_NS, "chapter"), StyleSheet.NULL);
widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
widget.insertText("1text before comment1");
- widget.insertComment();
- final INode comment = widget.getDocument().getChildAt(widget.getCaretOffset());
+ final INode comment = widget.insertComment();
widget.insertText("2comment text2");
widget.moveBy(1);
widget.insertText("3text after comment3");
@@ -112,13 +111,11 @@
widget.doWork(new Runnable() {
public void run() {
- widget.moveTo(comment.getStartOffset() + 1, false);
- widget.moveTo(comment.getEndOffset() - 1, true);
+ widget.selectContentOf(comment);
final IDocumentFragment fragment = widget.getSelectedFragment();
widget.deleteSelection();
- widget.moveBy(-1, false);
- widget.moveBy(1, true);
+ widget.select(comment);
widget.deleteSelection();
widget.insertFragment(fragment);
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
index 00c7daf..159500e 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* John Krasnay - initial API and implementation
* Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
@@ -37,7 +37,7 @@
private char[] content;
private int gapStart;
private int gapEnd;
- private final SortedSet<GapContentPosition> positions = new TreeSet<GapContentPosition>();
+ private TreeSet<GapContentPosition> positions = new TreeSet<GapContentPosition>();
/**
* Create a GapContent with the given initial capacity.
@@ -108,18 +108,21 @@
gapStart += text.length();
if (!atEnd) {
-
- // Update positions
- final GapContentPosition offsetPosition = new GapContentPosition(offset);
- for (final GapContentPosition position : positions.tailSet(offsetPosition)) {
- if (position.getOffset() >= offset) {
- position.setOffset(position.getOffset() + text.length());
- }
- }
-
+ movePositions(offset, text.length());
}
}
+ private void movePositions(final int startOffset, final int delta) {
+ final TreeSet<GapContentPosition> newPositions = new TreeSet<GapContentPosition>();
+ for (final GapContentPosition position : positions) {
+ if (position.getOffset() >= startOffset) {
+ position.setOffset(position.getOffset() + delta);
+ }
+ newPositions.add(position);
+ }
+ positions = newPositions;
+ }
+
public void insertTagMarker(final int offset) {
assertOffset(offset, 0, length());
@@ -152,13 +155,18 @@
moveGap(range.getEndOffset() + 1);
gapStart -= range.length();
+ final TreeSet<GapContentPosition> newPositions = new TreeSet<GapContentPosition>();
for (final GapContentPosition position : positions) {
if (position.getOffset() > range.getEndOffset()) {
position.setOffset(position.getOffset() - range.length());
+ newPositions.add(position);
} else if (position.getOffset() >= range.getStartOffset()) {
- position.setOffset(range.getStartOffset());
+ position.invalidate();
+ } else {
+ newPositions.add(position);
}
}
+ positions = newPositions;
}
public String getText() {
@@ -317,6 +325,10 @@
return useCount > 0;
};
+ public void invalidate() {
+ useCount = 0;
+ }
+
@Override
public int hashCode() {
final int prime = 31;