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) {


Reply via email to