You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@netbeans.apache.org by GitBox <gi...@apache.org> on 2018/09/15 14:39:02 UTC

[GitHub] matthiasblaesing closed pull request #603: [NETBEANS-980] Fix Home/End/Up/Down actions in line-wrapped editor

matthiasblaesing closed pull request #603: [NETBEANS-980] Fix Home/End/Up/Down actions in line-wrapped editor
URL: https://github.com/apache/incubator-netbeans/pull/603
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/ide/editor.lib/src/org/netbeans/editor/BaseKit.java b/ide/editor.lib/src/org/netbeans/editor/BaseKit.java
index 5356930164..b36c6c93a7 100644
--- a/ide/editor.lib/src/org/netbeans/editor/BaseKit.java
+++ b/ide/editor.lib/src/org/netbeans/editor/BaseKit.java
@@ -3388,6 +3388,10 @@ public void moveCarets(CaretMoveContext context) {
                                                     int textStartPos = Utilities.getRowFirstNonWhite(doc, lineStartPos);
                                                     if (textStartPos < 0) { // no text on the line
                                                         textStartPos = Utilities.getRowEnd(target, lineStartPos);
+                                                    } else if (textStartPos < lineStartPos) {
+                                                        /* NETBEANS-980: On a wrap line oher than the first; go only as
+                                                        far as to the first character on the wrap line. */
+                                                        textStartPos = lineStartPos;
                                                     }
                                                     if (dot == lineStartPos) { // go to the text start pos
                                                         dot = textStartPos;
@@ -3455,6 +3459,9 @@ public void moveCarets(CaretMoveContext context) {
                                 int textStartPos = Utilities.getRowFirstNonWhite(((BaseDocument)doc), lineStartPos);
                                 if (textStartPos < 0) { // no text on the line
                                     textStartPos = Utilities.getRowEnd(target, lineStartPos);
+                                } else if (textStartPos < lineStartPos) {
+                                   // Wrap line case (see above).
+                                   textStartPos = lineStartPos;
                                 }
                                 if (dot == lineStartPos) { // go to the text start pos
                                     dot = textStartPos;
diff --git a/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java b/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
index 2969f67a2b..d67c36a9e0 100644
--- a/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
+++ b/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
@@ -29,6 +29,8 @@
 import java.util.logging.Logger;
 import javax.swing.JComponent;
 import javax.swing.SwingConstants;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
 import javax.swing.text.Position.Bias;
 import javax.swing.text.TabableView;
 import javax.swing.text.View;
@@ -513,7 +515,7 @@ Shape modelToViewChecked(ParagraphView pView, int offset, Shape pAlloc, Bias bia
     public int viewToModelChecked(ParagraphView pView, double x, double y, Shape pAlloc, Bias[] biasReturn) {
         IndexAndAlloc indexAndAlloc = findIndexAndAlloc(pView, x, y, pAlloc);
         int offset = (indexAndAlloc != null)
-                ? indexAndAlloc.viewOrPart.viewToModelChecked(x, y, indexAndAlloc.alloc, biasReturn)
+                ? viewToModelWithAmbiguousWrapLineCaretAdustment(x, y, indexAndAlloc, biasReturn)
                 : pView.getStartOffset();
         return offset;
     }
@@ -613,7 +615,53 @@ private int visualPositionOnWrapLine(ParagraphView pView,
         Shape wrapLineAlloc = wrapLineAlloc(alloc, wrapLineIndex);
         IndexAndAlloc indexAndAlloc = findIndexAndAlloc(pView, x, wrapLineAlloc, wrapLine);
         double y = ViewUtils.shapeAsRect(indexAndAlloc.alloc).getY();
-        return indexAndAlloc.viewOrPart.viewToModelChecked(x, y, indexAndAlloc.alloc, biasRet);
+        return viewToModelWithAmbiguousWrapLineCaretAdustment(x, y, indexAndAlloc, biasRet);
+    }
+
+    private int viewToModelWithAmbiguousWrapLineCaretAdustment(
+            double x, double y, IndexAndAlloc indexAndAlloc, Bias[] biasRet)
+    {
+        final EditorView view = indexAndAlloc.viewOrPart;
+        int ret = view.viewToModelChecked(x, y, indexAndAlloc.alloc, biasRet);
+        /* NETBEANS-980: On wrap lines, the caret offset that corresponds to "right after the last
+        character on the current wrap line" is ambiguous, because it can equivalently be interpreted
+        as "right before the first character on the following wrap line" (because there is no explicit
+        newline character to increment the offset around). The NetBeans EditorKit uses the latter
+        interpretation when painting the caret and calculating visual positions via modelToView. Here,
+        in viewToModel, we need to ensure that the returned offset always corresponds to a caret on
+        the wrap line with the given Y position. Otherwise, keyboard actions such as UpAction,
+        DownAction, and EndLineAction (in o.n.editor.BaseKit), or clicking the mouse in the area to
+        the right of the end of the wrap line, will not work correctly.
+
+        The approach here is to map the end of the wrap line to a caret position right _before_ the
+        last character on the wrap line. Under word wrapping, said character will usually be a space
+        (or a hyphen; see NETBEANS-977). This is the same approach as is taken in JTextArea with word
+        wrapping enabled. The latter can be confirmed by entering a very long word in a word-wrapping
+        JTextArea so that the last character on the wrap line is a letter rather than a space, and
+        pressing the "End" key (Command+Right Arrow on Mac); the caret will end up right before the
+        last character on the wrap line. Other approaches are possible, such as relying on the caret
+        bias to differentiate the ambigous offsets, but the approach here seemed like the simplest
+        one to implement. */
+        if (isWrapped() && view.getLength() > 0 && ret >= view.getEndOffset()) {
+            /* As a small improvement, avoid applying the adjustment on the very last wrap line of a
+            paragraph, where it is not needed, and where the last character is likely to be something
+            other than a space. This adjustment ensures that the caret ends up in the expected place
+            if the user clicks on the right-hand half of the last character on the wrap line. (If the
+            user clicks _beyond_ the last character of the last wrap line, hit testing would encounter
+            a NewlineView instead of a HighlightsViewPart, which would yield the correct caret
+            position in any case.) */
+            boolean isLastWrapLineInParagraph = false;
+            try {
+                final Document doc = view.getDocument();
+                if (ret < doc.getLength())
+                    isLastWrapLineInParagraph = view.getDocument().getText(ret, 1).equals("\n");
+            } catch (BadLocationException e) {
+                // Ignore.
+            }
+            if (!isLastWrapLineInParagraph)
+                ret = view.getEndOffset() - 1;
+        }
+        return ret;
     }
     
     private int findWrapLineIndex(Rectangle2D pAllocRect, double y) {


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists