Author: rwhitcomb Date: Thu May 14 03:23:02 2020 New Revision: 1877713 URL: http://svn.apache.org/viewvc?rev=1877713&view=rev Log: PIVOT-1032: Fix the [MethodLength] error in TextAreaSkin by moving code to helper methods. Add a new version of "removeText" to TextArea as part of the general cleanup in the skin. Add comments to ClipboardContentListener to address style errors.
Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/ClipboardContentListener.java pivot/trunk/wtk/src/org/apache/pivot/wtk/TextArea.java pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/ClipboardContentListener.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/ClipboardContentListener.java?rev=1877713&r1=1877712&r2=1877713&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/ClipboardContentListener.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/ClipboardContentListener.java Thu May 14 03:23:02 2020 @@ -20,5 +20,16 @@ package org.apache.pivot.wtk; * Clipboard content listener interface. */ public interface ClipboardContentListener { - public void contentChanged(LocalManifest previousContent); + /** + * Called when the content of the clipboard has been changed. + * + * @param previousContent What used to be on the clipboard before + * the content changed. Note that this is a {@link LocalManifest} + * because the only time this listener is registered is via + * the {@link Clipboard#setContent(LocalManifest, ClipboardContentListener)} + * method and so the previous content will always be "local" (that is, + * generated/set by a Pivot application). + * <p> The current content can be accessed using {@link Clipboard#getContent}. + */ + void contentChanged(LocalManifest previousContent); } Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/TextArea.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/TextArea.java?rev=1877713&r1=1877712&r2=1877713&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/TextArea.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/TextArea.java Thu May 14 03:23:02 2020 @@ -735,6 +735,10 @@ public class TextArea extends Component } } + public void removeText(CharSpan charSelection) { + removeText(charSelection.start, charSelection.length, true); + } + public void removeText(int index, int count) { removeText(index, count, true); } Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java?rev=1877713&r1=1877712&r2=1877713&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TextAreaSkin.java Thu May 14 03:23:02 2020 @@ -56,6 +56,7 @@ import org.apache.pivot.wtk.Theme; */ public class TextAreaSkin extends ComponentSkin implements TextArea.Skin, TextAreaListener, TextAreaContentListener, TextAreaSelectionListener { + /** Callback to blink the caret waiting for input. */ private class BlinkCaretCallback implements Runnable { @Override public void run() { @@ -68,6 +69,7 @@ public class TextAreaSkin extends Compon } } + /** Callback to scroll a selection during mouse movement. */ private class ScrollSelectionCallback implements Runnable { @Override public void run() { @@ -148,6 +150,9 @@ public class TextAreaSkin extends Compon private ArrayList<TextAreaSkinParagraphView> paragraphViews = new ArrayList<>(); + private static final int DOUBLE_CLICK_COUNT = 2; + private static final int TRIPLE_CLICK_COUNT = 3; + private static final int SCROLL_RATE = 30; public TextAreaSkin() { @@ -155,7 +160,7 @@ public class TextAreaSkin extends Compon font = theme.getFont(); // TODO: find a way to set this in the theme defaults.json file - // TODO: these conflict with the values set in TerraTextAreaSkin... + // but these conflict with the values set in TerraTextAreaSkin... color = defaultForegroundColor(); selectionBackgroundColor = defaultForegroundColor(); inactiveSelectionBackgroundColor = defaultForegroundColor(); @@ -929,15 +934,14 @@ public class TextAreaSkin extends Compon if (button == Mouse.Button.LEFT) { int index = getInsertionPoint(x, y); if (index != -1) { - if (count == 2) { + if (count == DOUBLE_CLICK_COUNT) { int offset = getRowOffset(index); CharSpan charSpan = CharUtils.selectWord(textArea.getRowCharacters(index), index - offset); if (charSpan != null) { textArea.setSelection(charSpan.offset(offset)); } - } else if (count == 3) { - textArea.setSelection(textArea.getRowOffset(index), - textArea.getRowLength(index)); + } else if (count == TRIPLE_CLICK_COUNT) { + textArea.setSelection(textArea.getRowOffset(index), textArea.getRowLength(index)); } } } @@ -954,16 +958,14 @@ public class TextAreaSkin extends Compon if (textArea.isEditable()) { // Ignore characters in the control range and the ASCII delete // character as well as meta key presses - if (character > 0x1F && character != 0x7F - && !Keyboard.isPressed(Keyboard.Modifier.META)) { - int selectionLength = textArea.getSelectionLength(); + if (!Character.isISOControl(character) && !Keyboard.isPressed(Keyboard.Modifier.META)) { + CharSpan charSelection = textArea.getCharSelection(); - if (textArea.getCharacterCount() - selectionLength + 1 > textArea.getMaximumLength()) { + if (textArea.getCharacterCount() - charSelection.length + 1 > textArea.getMaximumLength()) { Toolkit.getDefaultToolkit().beep(); } else { - int selectionStart = textArea.getSelectionStart(); - textArea.removeText(selectionStart, selectionLength); - textArea.insertText(Character.toString(character), selectionStart); + textArea.removeText(charSelection); + textArea.insertText(Character.toString(character), charSelection.start); } showCaret(true); @@ -974,412 +976,474 @@ public class TextAreaSkin extends Compon return consumed; } - @Override - public boolean keyPressed(final Component component, final int keyCode, final Keyboard.KeyLocation keyLocation) { + private boolean doHome(final TextArea textArea, final boolean commandPressed, final boolean shiftPressed, + final CharSpan charSelection) { boolean consumed = false; + int start; + int length = charSelection.length; - if (paragraphViews.getLength() > 0) { - TextArea textArea = (TextArea) getComponent(); - boolean commandPressed = Keyboard.isPressed(Platform.getCommandModifier()); - boolean wordNavPressed = Keyboard.isPressed(Platform.getWordNavigationModifier()); - boolean shiftPressed = Keyboard.isPressed(Keyboard.Modifier.SHIFT); - boolean ctrlPressed = Keyboard.isPressed(Keyboard.Modifier.CTRL); - boolean metaPressed = Keyboard.isPressed(Keyboard.Modifier.META); - boolean isEditable = textArea.isEditable(); + if (commandPressed) { + // Find the very beginning of the text + start = 0; + } else { + // Find the start of the current line + start = getRowOffset(charSelection.start); + } - int selectionStart = textArea.getSelectionStart(); - int selectionLength = textArea.getSelectionLength(); - int count = textArea.getCharacterCount(); + if (shiftPressed) { + // Select from the beginning of the text to the current pivot position + if (selectDirection == SelectDirection.UP || selectDirection == SelectDirection.LEFT) { + length += charSelection.start - start; + } else { + length = charSelection.start - start; + } + selectDirection = SelectDirection.LEFT; + } else { + length = 0; + selectDirection = null; + } - if (keyCode == Keyboard.KeyCode.ENTER && acceptsEnter && isEditable - && Keyboard.getModifiers() == 0) { - textArea.removeText(selectionStart, selectionLength); - textArea.insertText("\n", selectionStart); + if (start >= 0) { + textArea.setSelection(start, length); + scrollCharacterToVisible(start); - consumed = true; - } else if (keyCode == Keyboard.KeyCode.DELETE && isEditable) { - if (selectionStart < count) { - textArea.removeText(selectionStart, Math.max(selectionLength, 1)); - anchor = -1; - consumed = true; - } - } else if (keyCode == Keyboard.KeyCode.BACKSPACE && isEditable) { - if (selectionLength == 0 && selectionStart > 0) { - textArea.removeText(selectionStart - 1, 1); - consumed = true; - } else { - textArea.removeText(selectionStart, selectionLength); - consumed = true; - } - anchor = -1; - } else if (keyCode == Keyboard.KeyCode.TAB && (acceptsTab != ctrlPressed) && isEditable) { - int rowOffset = textArea.getRowOffset(selectionStart); - int linePos = selectionStart - rowOffset; - StringBuilder tabBuilder = new StringBuilder(tabWidth); - for (int i = 0; i < tabWidth - (linePos % tabWidth); i++) { - tabBuilder.append(" "); - } + caretX = caret.x; - if (count - selectionLength + tabBuilder.length() > textArea.getMaximumLength()) { - Toolkit.getDefaultToolkit().beep(); - } else { - textArea.removeText(selectionStart, selectionLength); - textArea.insertText(tabBuilder, selectionStart); - } + consumed = true; + } - showCaret(true); + return consumed; + } - consumed = true; - } else if (keyCode == Keyboard.KeyCode.HOME - || (keyCode == Keyboard.KeyCode.LEFT && metaPressed)) { - int start; - - if (commandPressed) { - // Find the very beginning of the text - start = 0; - } else { - // Find the start of the current line - start = getRowOffset(selectionStart); - } + private boolean doEnd(final TextArea textArea, final boolean commandPressed, final boolean shiftPressed, + final CharSpan charSelection, final int count) { + boolean consumed = false; + int end; + int start = charSelection.start; + int length = charSelection.length; + int index = start + length; + + if (commandPressed) { + // Find the very end of the text + end = count; + } else { + // Find the end of the current line + end = getRowOffset(index) + getRowLength(index); + } - if (shiftPressed) { - // Select from the beginning of the text to the current pivot position - if (selectDirection == SelectDirection.UP || selectDirection == SelectDirection.LEFT) { - selectionLength += selectionStart - start; - } else { - selectionLength = selectionStart - start; - } - selectDirection = SelectDirection.LEFT; - } else { - selectionLength = 0; - selectDirection = null; - } + if (shiftPressed) { + // Select from current pivot position to the end of the text + if (selectDirection == SelectDirection.UP || selectDirection == SelectDirection.LEFT) { + start += length; + } + length = end - start; + selectDirection = SelectDirection.RIGHT; + } else { + start = end; + if (start < count && textArea.getCharacterAt(start) != '\n') { + start--; + } - if (start >= 0) { - textArea.setSelection(start, selectionLength); - scrollCharacterToVisible(start); + length = 0; + selectDirection = null; + } - caretX = caret.x; + if (start + length <= count) { + textArea.setSelection(start, length); + scrollCharacterToVisible(start + length); - consumed = true; - } - } else if (keyCode == Keyboard.KeyCode.END - || (keyCode == Keyboard.KeyCode.RIGHT && metaPressed)) { - int end; - int index = selectionStart + selectionLength; - - if (commandPressed) { - // Find the very end of the text - end = count; - } else { - // Find the end of the current line - int rowOffset = getRowOffset(index); - int rowLength = getRowLength(index); - end = rowOffset + rowLength; - } + caretX = caret.x; + if (selection != null) { + caretX += selection.getBounds2D().getWidth(); + } - if (shiftPressed) { - // Select from current pivot position to the end of the text - if (selectDirection == SelectDirection.UP || selectDirection == SelectDirection.LEFT) { - selectionStart += selectionLength; - } - selectionLength = end - selectionStart; - selectDirection = SelectDirection.RIGHT; - } else { - selectionStart = end; - if (selectionStart < count - && textArea.getCharacterAt(selectionStart) != '\n') { - selectionStart--; - } + consumed = true; + } - selectionLength = 0; - selectDirection = null; - } + return consumed; + } - if (selectionStart + selectionLength <= count) { - textArea.setSelection(selectionStart, selectionLength); - scrollCharacterToVisible(selectionStart + selectionLength); - - caretX = caret.x; - if (selection != null) { - caretX += selection.getBounds2D().getWidth(); - } + private boolean doLeft(final TextArea textArea, final boolean wordNavPressed, final boolean shiftPressed, + final CharSpan charSelection) { + boolean consumed = false; + int start = charSelection.start; + int length = charSelection.length; - consumed = true; + if (wordNavPressed) { + int wordStart = (selectDirection == SelectDirection.RIGHT) ? start + length : start; + // Move the caret to the start of the next word to the left + if (wordStart > 0) { + int index = CharUtils.findPriorWord(textArea.getCharacters(), wordStart); + + if (shiftPressed) { + // TODO: depending on prior selectDirection, may just reduce previous right selection + length += start - index; + selectDirection = SelectDirection.LEFT; + } else { + length = 0; + selectDirection = null; } - } else if (keyCode == Keyboard.KeyCode.LEFT) { - if (wordNavPressed) { - int wordStart = (selectDirection == SelectDirection.RIGHT) - ? selectionStart + selectionLength : selectionStart; - // Move the caret to the start of the next word to the left - if (wordStart > 0) { - int index = CharUtils.findPriorWord(textArea.getCharacters(), wordStart); - - if (shiftPressed) { - // TODO: depending on prior selectDirection, may just reduce previous right selection - selectionLength += selectionStart - index; - selectDirection = SelectDirection.LEFT; - } else { - selectionLength = 0; - selectDirection = null; - } - selectionStart = index; + start = index; + } + } else if (shiftPressed) { + if (anchor != -1) { + if (start < anchor) { + if (start > 0) { + start--; + length++; } - } else if (shiftPressed) { - if (anchor != -1) { - if (selectionStart < anchor) { - if (selectionStart > 0) { - selectionStart--; - selectionLength++; - } - selectDirection = SelectDirection.LEFT; - } else { - if (selectionLength > 0) { - selectionLength--; - } else { - selectionStart--; - selectionLength++; - selectDirection = SelectDirection.LEFT; - } - } + selectDirection = SelectDirection.LEFT; + } else { + if (length > 0) { + length--; } else { - // Add the previous character to the selection - anchor = selectionStart; - if (selectionStart > 0) { - selectionStart--; - selectionLength++; - } + start--; + length++; selectDirection = SelectDirection.LEFT; } - } else { - // Move the caret back by one character - if (selectionLength == 0 && selectionStart > 0) { - selectionStart--; - } - - // Clear the selection - anchor = -1; - selectionLength = 0; - selectDirection = null; } + } else { + // Add the previous character to the selection + anchor = start; + if (start > 0) { + start--; + length++; + } + selectDirection = SelectDirection.LEFT; + } + } else { + // Move the caret back by one character + if (length == 0 && start > 0) { + start--; + } - if (selectionStart >= 0) { - textArea.setSelection(selectionStart, selectionLength); - scrollCharacterToVisible(selectionStart); + // Clear the selection + anchor = -1; + length = 0; + selectDirection = null; + } - caretX = caret.x; + if (start >= 0) { + textArea.setSelection(start, length); + scrollCharacterToVisible(start); - consumed = true; + caretX = caret.x; + + consumed = true; + } + + return consumed; + } + + private boolean doRight(final TextArea textArea, final boolean wordNavPressed, final boolean shiftPressed, + final CharSpan charSelection, final int count) { + boolean consumed = false; + int start = charSelection.start; + int length = charSelection.length; + + if (wordNavPressed) { + int wordStart = (selectDirection == SelectDirection.LEFT) ? start : start + length; + // Move the caret to the start of the next word to the right + if (wordStart < count) { + int index = CharUtils.findNextWord(textArea.getCharacters(), wordStart); + + if (shiftPressed) { + // TODO: depending on prior selectDirection, may just reduce previous left selection + length = index - start; + } else { + start = index; + length = 0; } - } else if (keyCode == Keyboard.KeyCode.RIGHT) { - if (wordNavPressed) { - int wordStart = (selectDirection == SelectDirection.LEFT) - ? selectionStart : selectionStart + selectionLength; - // Move the caret to the start of the next word to the right - if (wordStart < count) { - int index = CharUtils.findNextWord(textArea.getCharacters(), wordStart); - - if (shiftPressed) { - // TODO: depending on prior selectDirection, may just reduce previous left selection - selectionLength = index - selectionStart; - } else { - selectionStart = index; - selectionLength = 0; - } - } - } else if (shiftPressed) { - if (anchor != -1) { - if (selectionStart < anchor) { - selectionStart++; - selectionLength--; - } else { - selectionLength++; - selectDirection = SelectDirection.RIGHT; - } - } else { - // Add the next character to the selection - anchor = selectionStart; - selectionLength++; - selectDirection = SelectDirection.RIGHT; - } + } + } else if (shiftPressed) { + if (anchor != -1) { + if (start < anchor) { + start++; + length--; } else { - // Move the caret forward by one character - if (selectionLength == 0) { - selectionStart++; - } else { - selectionStart += selectionLength; - } - - // Clear the selection - anchor = -1; - selectionLength = 0; - selectDirection = null; + length++; + selectDirection = SelectDirection.RIGHT; } + } else { + // Add the next character to the selection + anchor = start; + length++; + selectDirection = SelectDirection.RIGHT; + } + } else { + // Move the caret forward by one character + if (length == 0) { + start++; + } else { + start += length; + } - if (selectionStart + selectionLength <= count) { - textArea.setSelection(selectionStart, selectionLength); - scrollCharacterToVisible(selectionStart + selectionLength); - - caretX = caret.x; - if (selection != null) { - caretX += selection.getBounds2D().getWidth(); - } + // Clear the selection + anchor = -1; + length = 0; + selectDirection = null; + } - consumed = true; + if (start + length <= count) { + textArea.setSelection(start, length); + scrollCharacterToVisible(start + length); + + caretX = caret.x; + if (selection != null) { + caretX += selection.getBounds2D().getWidth(); + } + + consumed = true; + } + + return consumed; + } + + private boolean doUp(final TextArea textArea, final boolean shiftPressed, final CharSpan charSelection) { + int start = charSelection.start; + int length = charSelection.length; + int index = -1; + + if (shiftPressed) { + if (anchor == -1) { + anchor = start; + index = getNextInsertionPoint(caretX, start, TextArea.ScrollDirection.UP); + if (index != -1) { + length = start - index; } - } else if (keyCode == Keyboard.KeyCode.UP) { - int index = -1; - if (shiftPressed) { - if (anchor == -1) { - anchor = selectionStart; - index = getNextInsertionPoint(caretX, selectionStart, - TextArea.ScrollDirection.UP); - if (index != -1) { - selectionLength = selectionStart - index; - } - } else { - if (selectionStart < anchor) { - // continue upwards - index = getNextInsertionPoint(caretX, selectionStart, - TextArea.ScrollDirection.UP); - if (index != -1) { - selectionLength = selectionStart + selectionLength - index; - } - } else { - // reduce downward size - Bounds trailingSelectionBounds = getCharacterBounds(selectionStart - + selectionLength - 1); - int x = trailingSelectionBounds.x + trailingSelectionBounds.width; - index = getNextInsertionPoint(x, selectionStart + selectionLength - 1, - TextArea.ScrollDirection.UP); - if (index != -1) { - if (index < anchor) { - selectionLength = anchor - index; - } else { - selectionLength = index - selectionStart; - index = selectionStart; - } - } - } + } else { + if (start < anchor) { + // continue upwards + index = getNextInsertionPoint(caretX, start, TextArea.ScrollDirection.UP); + if (index != -1) { + length = start + length - index; } } else { - index = getNextInsertionPoint(caretX, selectionStart, - TextArea.ScrollDirection.UP); + // reduce downward size + Bounds trailingSelectionBounds = getCharacterBounds(start + length - 1); + int x = trailingSelectionBounds.x + trailingSelectionBounds.width; + index = getNextInsertionPoint(x, start + length - 1, TextArea.ScrollDirection.UP); if (index != -1) { - selectionLength = 0; + if (index < anchor) { + length = anchor - index; + } else { + length = index - start; + index = start; + } } - anchor = -1; } + } + } else { + index = getNextInsertionPoint(caretX, start, TextArea.ScrollDirection.UP); + if (index != -1) { + length = 0; + } + anchor = -1; + } + + if (index != -1) { + textArea.setSelection(index, length); + scrollCharacterToVisible(index); + caretX = caret.x; + } + + return true; + } + private boolean doDown(final TextArea textArea, final boolean shiftPressed, + final CharSpan charSelection, final int count) { + int start = charSelection.start; + int length = charSelection.length; + int from, index, x; + + if (shiftPressed) { + if (anchor == -1) { + anchor = start; + index = getNextInsertionPoint(caretX, start, TextArea.ScrollDirection.DOWN); if (index != -1) { - textArea.setSelection(index, selectionLength); - scrollCharacterToVisible(index); - caretX = caret.x; + length = index - start; } + } else { + if (start < anchor) { + // Reducing upward size + // Get next insertion point from leading selection character + from = start; + x = caretX; - consumed = true; - } else if (keyCode == Keyboard.KeyCode.DOWN) { - if (shiftPressed) { - int from; - int x; - int index; - - if (anchor == -1) { - anchor = selectionStart; - index = getNextInsertionPoint(caretX, selectionStart, - TextArea.ScrollDirection.DOWN); - if (index != -1) { - selectionLength = index - selectionStart; - } - } else { - if (selectionStart < anchor) { - // Reducing upward size - // Get next insertion point from leading selection character - from = selectionStart; - x = caretX; - - index = getNextInsertionPoint(x, from, TextArea.ScrollDirection.DOWN); - - if (index != -1) { - if (index < anchor) { - selectionStart = index; - selectionLength = anchor - index; - } else { - selectionStart = anchor; - selectionLength = index - anchor; - } - - textArea.setSelection(selectionStart, selectionLength); - scrollCharacterToVisible(selectionStart); - } + index = getNextInsertionPoint(x, from, TextArea.ScrollDirection.DOWN); + + if (index != -1) { + if (index < anchor) { + // New position is still above the original anchor then reduce the selection + start = index; + length = anchor - index; } else { - // Increasing downward size - // Get next insertion point from right edge of trailing selection - // character - from = selectionStart + selectionLength - 1; - - Bounds trailingSelectionBounds = getCharacterBounds(from); - x = trailingSelectionBounds.x + trailingSelectionBounds.width; - - index = getNextInsertionPoint(x, from, TextArea.ScrollDirection.DOWN); - - if (index != -1) { - // If the next character is a paragraph terminator and is - // not the final terminator character, increment - // the selection - if (index < count - 1 - && textArea.getCharacterAt(index) == '\n') { - index++; - } - - textArea.setSelection(selectionStart, index - selectionStart); - scrollCharacterToVisible(index); - } + // New position is now below the original anchor then reverse selection + start = anchor; + length = index - anchor; } + + textArea.setSelection(start, length); + scrollCharacterToVisible(start); } } else { - int from; - if (selectionLength == 0) { - // Get next insertion point from leading selection character - from = selectionStart; - } else { - // Get next insertion point from trailing selection character - from = selectionStart + selectionLength - 1; - } + // Increasing downward size + // Get next insertion point from right edge of trailing selection character + from = start + length - 1; - int index = getNextInsertionPoint(caretX, from, TextArea.ScrollDirection.DOWN); + Bounds trailingSelectionBounds = getCharacterBounds(from); + x = trailingSelectionBounds.x + trailingSelectionBounds.width; + + index = getNextInsertionPoint(x, from, TextArea.ScrollDirection.DOWN); if (index != -1) { - textArea.setSelection(index, 0); + // If the next character is a paragraph terminator and is + // not the final terminator character, increment the selection + if (index < count - 1 && textArea.getCharacterAt(index) == '\n') { + index++; + } + + textArea.setSelection(start, index - start); scrollCharacterToVisible(index); - caretX = caret.x; } - anchor = -1; } + } + } else { + if (length == 0) { + // Get next insertion point from leading selection character + from = start; + } else { + // Get next insertion point from trailing selection character + from = start + length - 1; + } + + index = getNextInsertionPoint(caretX, from, TextArea.ScrollDirection.DOWN); + + if (index != -1) { + textArea.setSelection(index, 0); + scrollCharacterToVisible(index); + caretX = caret.x; + } + anchor = -1; + } + return true; + } + + private boolean doCommand(final TextArea textArea, final int keyCode, + final boolean isEditable, final boolean shiftPressed, final int count) { + boolean consumed = false; + + switch (keyCode) { + case Keyboard.KeyCode.A: + textArea.setSelection(0, count); consumed = true; - } else if (commandPressed) { - if (keyCode == Keyboard.KeyCode.A) { - textArea.setSelection(0, count); - consumed = true; - } else if (keyCode == Keyboard.KeyCode.X && isEditable) { + break; + case Keyboard.KeyCode.X: + if (isEditable) { textArea.cut(); consumed = true; - } else if (keyCode == Keyboard.KeyCode.C) { - textArea.copy(); - consumed = true; - } else if (keyCode == Keyboard.KeyCode.V && isEditable) { + } + break; + case Keyboard.KeyCode.C: + textArea.copy(); + consumed = true; + break; + case Keyboard.KeyCode.V: + if (isEditable) { textArea.paste(); consumed = true; - } else if (keyCode == Keyboard.KeyCode.Z && isEditable) { + } + break; + case Keyboard.KeyCode.Z: + if (isEditable) { if (!shiftPressed) { textArea.undo(); } consumed = true; - } else if (keyCode == Keyboard.KeyCode.TAB) { + } + break; + default: + break; + } + + return consumed; + } + + @Override + public boolean keyPressed(final Component component, final int keyCode, final Keyboard.KeyLocation keyLocation) { + boolean consumed = false; + + if (paragraphViews.getLength() > 0) { + TextArea textArea = (TextArea) getComponent(); + boolean commandPressed = Keyboard.isPressed(Platform.getCommandModifier()); + boolean wordNavPressed = Keyboard.isPressed(Platform.getWordNavigationModifier()); + boolean shiftPressed = Keyboard.isPressed(Keyboard.Modifier.SHIFT); + boolean ctrlPressed = Keyboard.isPressed(Keyboard.Modifier.CTRL); + boolean metaPressed = Keyboard.isPressed(Keyboard.Modifier.META); + boolean isEditable = textArea.isEditable(); + + CharSpan charSelection = textArea.getCharSelection(); + int selectionStart = charSelection.start; + int selectionLength = charSelection.length; + int count = textArea.getCharacterCount(); + + if (keyCode == Keyboard.KeyCode.ENTER && acceptsEnter && isEditable + && Keyboard.getModifiers() == 0) { + textArea.removeText(charSelection); + textArea.insertText("\n", selectionStart); + consumed = true; + } else if (keyCode == Keyboard.KeyCode.DELETE && isEditable) { + if (selectionStart < count) { + textArea.removeText(selectionStart, Math.max(selectionLength, 1)); + anchor = -1; + consumed = true; + } + } else if (keyCode == Keyboard.KeyCode.BACKSPACE && isEditable) { + if (selectionLength == 0 && selectionStart > 0) { + textArea.removeText(selectionStart - 1, 1); + consumed = true; + } else { + textArea.removeText(charSelection); + consumed = true; + } + anchor = -1; + } else if (keyCode == Keyboard.KeyCode.TAB && (acceptsTab != ctrlPressed) && isEditable) { + int rowOffset = textArea.getRowOffset(selectionStart); + int linePos = selectionStart - rowOffset; + StringBuilder tabBuilder = new StringBuilder(tabWidth); + for (int i = 0; i < tabWidth - (linePos % tabWidth); i++) { + tabBuilder.append(" "); + } + + if (count - selectionLength + tabBuilder.length() > textArea.getMaximumLength()) { + Toolkit.getDefaultToolkit().beep(); + } else { + textArea.removeText(charSelection); + textArea.insertText(tabBuilder, selectionStart); + } + + showCaret(true); + consumed = true; + } else if (keyCode == Keyboard.KeyCode.HOME || (keyCode == Keyboard.KeyCode.LEFT && metaPressed)) { + consumed = doHome(textArea, commandPressed, shiftPressed, charSelection); + } else if (keyCode == Keyboard.KeyCode.END || (keyCode == Keyboard.KeyCode.RIGHT && metaPressed)) { + consumed = doEnd(textArea, commandPressed, shiftPressed, charSelection, count); + } else if (keyCode == Keyboard.KeyCode.LEFT) { + consumed = doLeft(textArea, wordNavPressed, shiftPressed, charSelection); + } else if (keyCode == Keyboard.KeyCode.RIGHT) { + consumed = doRight(textArea, wordNavPressed, shiftPressed, charSelection, count); + } else if (keyCode == Keyboard.KeyCode.UP) { + consumed = doUp(textArea, shiftPressed, charSelection); + } else if (keyCode == Keyboard.KeyCode.DOWN) { + consumed = doDown(textArea, shiftPressed, charSelection, count); + } else if (commandPressed) { + if (keyCode == Keyboard.KeyCode.TAB) { // Only here if acceptsTab is false consumed = super.keyPressed(component, keyCode, keyLocation); + } else { + consumed = doCommand(textArea, keyCode, isEditable, shiftPressed, count); } } else if (keyCode == Keyboard.KeyCode.INSERT) { if (shiftPressed && isEditable) {