Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Pazderski2019-10-05 11:13:57 +0000
committerPaul Pazderski2019-11-12 11:36:00 +0000
commitb61668507b32b353ea60da3fbd24bcbf7717afda (patch)
tree3776aa2c57cf003c58a2a24132c70efc52293ed0 /org.eclipse.ui.console
parent0ad20a3402532969edd5cab954430b6b6f36f588 (diff)
downloadeclipse.platform.debug-b61668507b32b353ea60da3fbd24bcbf7717afda.tar.gz
eclipse.platform.debug-b61668507b32b353ea60da3fbd24bcbf7717afda.tar.xz
eclipse.platform.debug-b61668507b32b353ea60da3fbd24bcbf7717afda.zip
Bug 552014 - [console] Input problem with fixed width console and IMEI20191112-1800
When IME is started at end of fixed width line the first stroke is immediately inserted as character and the IME continued after. Change-Id: I9a197f49b9b9aae8c279fe5638fa5278d66294c8 Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
Diffstat (limited to 'org.eclipse.ui.console')
-rw-r--r--org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleDocumentAdapter.java108
1 files changed, 69 insertions, 39 deletions
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleDocumentAdapter.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleDocumentAdapter.java
index 88bc3197c..89a545a95 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleDocumentAdapter.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleDocumentAdapter.java
@@ -135,6 +135,47 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
private int[] widgetLineOffsets = new int[1];
/**
+ * The fact that wrapped lines are new lines without a newline delimiter leads
+ * to some hard to handle edge cases since all involved interfaces (implicit)
+ * assume a newline has its unique offset.
+ * <p>
+ * Consider a fixed with of 10 and a console filled with (automatically wrapped)
+ * content of:
+ * </p>
+ *
+ * <pre>
+ * 0123456789
+ * 0
+ * </pre>
+ *
+ * <p>
+ * If we remove the last character ('0') we must set replaceLineCount to 1 since
+ * there is one line less due to the unwrapped line. The replaceLineCount is
+ * necessary so that StyledTextRenderer updates the lines which possible follow
+ * below and have changed due to moved content.
+ * </p>
+ * <p>
+ * But StyledTextRenderer presumes that the line index where the event occurs is
+ * the same before and after the text change. This is not the case for our auto
+ * wrapped lines since getLineAtOffset(10) is 1 before text change and 0 after
+ * </p>
+ * <p>
+ * To solve this unlucky situation we will lie to StyledText(Renderer) for the
+ * short time between text changing event and actual text change. If we know the
+ * same (start) offset will yield a different line index before and after change
+ * we will return for this offset the line index it will have after the change
+ * already before the change is applied. In this example if StyledText ask for
+ * getLineAtOffset(10) we return 0 already before the text is actual changed.
+ * </p>
+ * <p>
+ * This field store the offset for which we should preempt the new line index.
+ * It must be an offset at fixed width border (or negative for none) because
+ * only those have the potential for two different line indexes at same offset.
+ * </p>
+ */
+ private int preemptLineWrapChange = -1;
+
+ /**
* New {@link ConsoleDocumentAdapter} with no {@link IDocument} connected yet.
*
* @param width fixed console width to enforce text wrap or &lt;= 0 to disable
@@ -264,6 +305,13 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
// is the index before the insertion index.
widgetLine = (-widgetLine) - 2;
}
+ if (offset == preemptLineWrapChange) {
+ // The requested offset is at fixed width border. In some text change situations
+ // we must return the line index it will have after the change even if the
+ // change is not applied yet. See #preemptLineWrapChange Javadoc for more
+ // details.
+ widgetLine--;
+ }
return widgetLine;
}
}
@@ -385,10 +433,10 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
* @throws BadLocationException if document event is invalid
*/
private TextChangingEvent generateTextChangingEvent(DocumentEvent event) throws BadLocationException {
- String newText = event.getText() == null ? "" : event.getText(); //$NON-NLS-1$
- int newTextLength = newText.length();
- int eventOffset = event.getOffset();
- int eventLength = event.getLength();
+ final String newText = event.getText() == null ? "" : event.getText(); //$NON-NLS-1$
+ final int newTextLength = newText.length();
+ final int eventOffset = event.getOffset();
+ final int eventLength = event.getLength();
int replaceLineCount = 0;
int newLineCount = 0;
@@ -400,45 +448,14 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
// single character inserted at first offset can, from StyledText-Widgets
// perspective, change the content of every line.
- if (newTextLength >= 0 || eventLength > 0) {
+ if (newTextLength > 0 || eventLength > 0) {
// In this method first and last refer to the first and last line affected by
// the current document event
- final int firstDocLineIndex = document.getLineOfOffset(eventOffset);
- final int firstDocLineOffset = document.getLineOffset(firstDocLineIndex);
-
- if (eventOffset != firstDocLineOffset && (eventOffset - firstDocLineOffset) % fixedConsoleWidth == 0) {
- // event start is at fixed width border
- // XXX: the trick here is important to do the impossible
- // The fact that wrapped lines are new lines without a newline delimiter leads
- // to some (nearly) impossible edge cases since all involved interfaces
- // (implicit) assume a newline has its unique offset.
- //
- // Consider a fixed with of 10 and a console filled with (automatically wrapped)
- // content of:
- // 0123456789
- // 0
- // If we remove the last character ('0') we must set replaceLineCount to 1 since
- // there is one line less due to the unwrapped line. The replaceLineCount is
- // necessary so that StyledTextRenderer updates the lines which possible follow
- // below and have changed due to moved content.
- // But StyledTextRenderer presumes that the line index where the event occurs is
- // the same before and after the text change. This is not the case for our auto
- // wrapped lines since getLineAtOffset(10) is 1 before text change and 0 after.
- //
- // To solve this unlucky situation we simply never send text change event
- // occurring at the fixed width wrap border. If such an document change happens
- // we expand the text change to include also the character before the wrap
- // border.
- eventOffset--;
- eventLength++;
- newText = document.get(eventOffset, 1) + newText;
- newTextLength++;
- }
-
final int eventEnd = eventOffset + eventLength;
final int firstWidgetLineIndex = getLineOfOffset(eventOffset);
final int firstWidgetLineOffset = getLineOffset(firstWidgetLineIndex);
+ final int firstInsertLength;
final int lastInsertLength;
int lastDocLineLengthDiff = -eventLength;
@@ -446,6 +463,7 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
Match newLineMatch = docLegalLineDelimiterMatcher.indexOf(newText, newTextOffset);
if (newLineMatch == null) {
// single line insert
+ firstInsertLength = newTextLength;
lastInsertLength = eventOffset - firstWidgetLineOffset + newTextLength;
lastDocLineLengthDiff += newTextLength;
} else {
@@ -458,7 +476,7 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
// 3. Last line: everything (including) last line delimiter to end of inserted
// text
- final int firstInsertLength = newLineMatch.getOffset();
+ firstInsertLength = newLineMatch.getOffset();
// newLineCount here is numbers of lines required if text is wrapped -1 because
// we start inserting in an existing line and +1 for the first line delimiter we
// had found
@@ -512,6 +530,18 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
lastAffectedWidgetLineIndex--;
}
replaceLineCount = lastAffectedWidgetLineIndex - firstWidgetLineIndex;
+
+ if (firstInsertLength == 0 && eventLength > 0 && affectedContentAfterRange == 0) {
+ final int firstDocLineOffset = document.getLineInformationOfOffset(eventOffset).getOffset();
+ if (eventOffset != firstDocLineOffset && (eventOffset - firstDocLineOffset) % fixedConsoleWidth == 0) {
+ // Text change produce a tricky wrapped line change. Change start at fixed width
+ // border and is at start of wrapped line because there is wrapped content after
+ // event start. After change there is no more wrapped content after so the same
+ // event start offset is now one widget line above.
+ replaceLineCount++;
+ preemptLineWrapChange = eventOffset;
+ }
+ }
}
final TextChangingEvent changingEvent = new TextChangingEvent(this);
@@ -550,7 +580,7 @@ public class ConsoleDocumentAdapter implements IDocumentAdapter, IDocumentListen
@Override
public synchronized void documentChanged(DocumentEvent event) {
-
+ preemptLineWrapChange = -1;
updateWidgetOffsets(event.getOffset());
TextChangedEvent changeEvent = new TextChangedEvent(this);

Back to the top