Bug 448762: StyledText#replaceTextRange(..) sends wrong selection event (length==0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index 334af28..eebede1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -9647,7 +9647,11 @@
setBlockSelectionOffset(start, end, sendEvent);
}
} else {
- clearSelection(sendEvent);
+ int charCount = content.getCharCount();
+ // called internally to remove selection after text is removed
+ // therefore make sure redraw range is valid.
+ int redrawX = Math.min(selection.x, charCount);
+ int redrawY = Math.min(selection.y, charCount);
if (length < 0) {
selectionAnchor = selection.y = end;
selection.x = start;
@@ -9657,7 +9661,14 @@
selection.y = end;
setCaretOffset(end, PREVIOUS_OFFSET_TRAILING);
}
- internalRedrawRange(selection.x, selection.y - selection.x);
+ redrawX = Math.min(redrawX, selection.x);
+ redrawY = Math.max(redrawY, selection.y);
+ if (redrawY - redrawX > 0) {
+ internalRedrawRange(redrawX, redrawY - redrawX);
+ }
+ if (sendEvent) {
+ sendSelectionEvent();
+ }
sendAccessibleTextCaretMoved();
}
}
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
index 25cfd7f..dd59644 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
@@ -11,45 +11,18 @@
package org.eclipse.swt.tests.junit;
-import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.*;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.BidiSegmentEvent;
-import org.eclipse.swt.custom.BidiSegmentListener;
-import org.eclipse.swt.custom.ExtendedModifyEvent;
-import org.eclipse.swt.custom.ExtendedModifyListener;
-import org.eclipse.swt.custom.LineBackgroundEvent;
-import org.eclipse.swt.custom.LineBackgroundListener;
-import org.eclipse.swt.custom.LineStyleEvent;
-import org.eclipse.swt.custom.LineStyleListener;
-import org.eclipse.swt.custom.ST;
-import org.eclipse.swt.custom.StyleRange;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.custom.StyledTextContent;
-import org.eclipse.swt.custom.TextChangeListener;
-import org.eclipse.swt.custom.VerifyKeyListener;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.RTFTransfer;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.internal.BidiUtil;
-import org.eclipse.swt.printing.Printer;
-import org.eclipse.swt.widgets.Caret;
-import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.*;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.printing.*;
+import org.eclipse.swt.widgets.*;
/**
* Automated Test Suite for class org.eclipse.swt.custom.StyledText
@@ -2864,15 +2837,24 @@
}
public void test_replaceTextRangeIILjava_lang_String(){
- String defaultText = "line0\n\rline1\n\rline2\n\r";
- int defaultTextLength = defaultText.length();
- int selectionStart = 7;
- int selectionLength = 7;
- int replaceStart = selectionStart + selectionLength + 1;
- int replaceLength = 5;
+ final String defaultText = "line0\n\rline1\n\rline2\n\r";
+ final int defaultTextLength = defaultText.length();
+ final int selectionStart = 7;
+ final int selectionLength = 7;
+ final int replaceStart = selectionStart + selectionLength + 1;
+ final int replaceLength = 5;
boolean exceptionThrown = false;
- String newText = "newline0\n\rnewline1";
- int newTextLength = newText.length();
+ final String newText = "newline0\n\rnewline1";
+ final int newTextLength = newText.length();
+ class TestSelectionListener extends SelectionAdapter {
+ public Point eventSelection = new Point(0, 0);
+ public void widgetSelected(SelectionEvent e) {
+ eventSelection.x = e.x;
+ eventSelection.y = e.y;
+ }
+ }
+ final TestSelectionListener selectionListener = new TestSelectionListener();
+ text.addSelectionListener(selectionListener);
// insert text
// within range
@@ -2891,6 +2873,7 @@
text.replaceTextRange(0, 0, newText);
assertTrue(":c:", text.getCharCount() == defaultTextLength + newTextLength);
assertTrue(":d:", text.getSelectionRange().x == selectionStart + newTextLength && text.getSelectionRange().y == selectionLength);
+ assertEquals(text.getSelection(), selectionListener.eventSelection);
// intersecting selection
@@ -2900,6 +2883,7 @@
text.replaceTextRange(selectionStart + 1, 0, newText);
assertTrue(":e:", text.getCharCount() == defaultTextLength + newTextLength);
assertTrue(":f:", text.getSelectionRange().x == selectionStart + 1 + newTextLength && text.getSelectionRange().y == 0);
+ assertEquals(text.getSelection(), selectionListener.eventSelection);
// out of range
text.setText(defaultText);
@@ -2972,6 +2956,7 @@
text.replaceTextRange(0, replaceLength, newText);
assertTrue(":r:", text.getCharCount() == defaultTextLength + newTextLength - replaceLength);
assertTrue(":s:", text.getSelectionRange().x == selectionStart + newTextLength - replaceLength && text.getSelectionRange().y == selectionLength);
+ assertEquals(text.getSelection(), selectionListener.eventSelection);
// intersecting selection
text.setText(defaultText);
@@ -2980,6 +2965,7 @@
text.replaceTextRange(selectionStart + 1, replaceLength, newText);
assertTrue(":t:", text.getCharCount() == defaultTextLength + newTextLength - replaceLength);
assertTrue(":u:", text.getSelectionRange().x == selectionStart + 1 + newTextLength && text.getSelectionRange().y == 0);
+ assertEquals(text.getSelection(), selectionListener.eventSelection);
// out of range
text.setText(defaultText);
@@ -3001,6 +2987,7 @@
}
assertTrue(":w:", exceptionThrown);
assertTrue(":x:", text.getSelectionRange().x == selectionStart && text.getSelectionRange().y == selectionLength);
+ text.removeSelectionListener(selectionListener);
}
public void test_selectAll() {