Hi,
the following patch implements the above mentioned method in View and its
EastWest and NorthSouth cousins in CompositeView. *However* I could not provide
an implementation I am feeling 100% sure about. It works for our JTextField and
JTextArea with and without line wrap but I am sure that it will lead to problems
some day: If someone knows the JDK's code and writes a subclass of CompositeView
that depends on their implementation it will break on our's.

Therefore I decided to document my intentions and assumptions when implementing
the two CompositeView methods and provided a PR[0][1] for each one. I hope that
this will help to get the implementation right when a free application shows up
that depends on the proper behavior.

The getNextVisualPositionFrom methods are very important for a proper cursor
navigation implementation which I described in PR 27220. This patch is the first
part to fix it.

The ChangeLog:

2006-04-28  Robert Schuster  <[EMAIL PROTECTED]>

        * javax/swing/text/View.java:
        (getNextVisualPositionFrom): Rewritten.
        * javax/swing/text/CompositeView.java:
        (getNextEastWestVisualPositionFrom): Partly implemented.
        (getNextNorthSouthVisualPositionFrom): Partly implemented.

cya
Robert

[0] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27345
[1] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27346
Index: javax/swing/text/View.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/View.java,v
retrieving revision 1.30
diff -u -r1.30 View.java
--- javax/swing/text/View.java	1 Mar 2006 20:39:49 -0000	1.30
+++ javax/swing/text/View.java	28 Apr 2006 10:25:08 -0000
@@ -1,5 +1,5 @@
 /* View.java -- 
-   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -733,23 +733,35 @@
     throws BadLocationException
   {
     int ret = pos;
+    Rectangle r;
+
     switch (d)
     {
-      case WEST:
-        ret = pos - 1;
-        break;
       case EAST:
-        ret = pos + 1;
+        // TODO: take component orientation into account?
+        // Note: If pos is below zero the implementation will return
+        // pos + 1 regardless of whether that value is a correct offset
+        // in the document model. However this is what the RI does.
+        ret = Math.min(pos + 1, getEndOffset());
+        break;
+      case WEST:
+        // TODO: take component orientation into account?
+        ret = Math.max(pos - 1, getStartOffset());
         break;
       case NORTH:
-        // TODO: Implement this
+        // Try to find a suitable offset by examining the area above. 
+        r =  modelToView(pos, a, b).getBounds();
+        ret = viewToModel(r.x, r.y - 1, a, biasRet);
         break;
       case SOUTH:
-        // TODO: Implement this
+        // Try to find a suitable offset by examining the area below. 
+        r =  modelToView(pos, a, b).getBounds();
+        ret = viewToModel(r.x + r.width, r.y + r.height, a, biasRet);
         break;
       default:
         throw new IllegalArgumentException("Illegal value for d");
     }
+    
     return ret;
   }
 }
Index: javax/swing/text/CompositeView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/CompositeView.java,v
retrieving revision 1.17
diff -u -r1.17 CompositeView.java
--- javax/swing/text/CompositeView.java	1 Apr 2006 15:22:07 -0000	1.17
+++ javax/swing/text/CompositeView.java	28 Apr 2006 10:25:08 -0000
@@ -633,8 +633,51 @@
                                                     Position.Bias[] biasRet)
     throws BadLocationException
   {
-    // FIXME: Implement this correctly.
-    return pos;
+    // TODO: It is unknown to me how this method has to be implemented and
+    // there is no specification telling me how to do it properly. Therefore
+    // the implementation was done for cases that are known.
+    //
+    // If this method ever happens to act silly for your particular case then
+    // it is likely that it is a cause of not knowing about your case when it
+    // was implemented first. You are free to fix the behavior.
+    //
+    // Here are the assumptions that lead to the implementation:
+    // If direction is NORTH chose the View preceding the one that contains the
+    // offset 'pos' (imagine the views are stacked on top of each other where
+    // the top is 0 and the bottom is getViewCount()-1.
+    // Consecutively when the direction is SOUTH the View following the one
+    // the offset 'pos' lies in is questioned.
+    //
+    // This limitation is described as PR 27345.
+    int index = getViewIndex(pos, b);
+    View v = null;
+    
+    if (index == -1)
+      return pos;
+
+    switch (direction)
+    {
+      case NORTH:
+        // If we cannot calculate a proper offset return the one that was
+        // provided.
+        if (index <= 0)
+          return pos;
+        
+        v = getView(index - 1);
+        break;
+      case SOUTH:
+        // If we cannot calculate a proper offset return the one that was
+        // provided.
+        if (index >= getViewCount() - 1)
+          return pos;
+        
+        v = getView(index + 1);
+        break;
+      default:
+          throw new IllegalArgumentException();
+    }
+    
+    return v.getNextVisualPositionFrom(pos, b, a, direction, biasRet);
   }
 
   /**
@@ -667,8 +710,55 @@
                                                   Position.Bias[] biasRet)
     throws BadLocationException
   {
-    // FIXME: Implement this correctly.
-    return pos;
+    // TODO: It is unknown to me how this method has to be implemented and
+    // there is no specification telling me how to do it properly. Therefore
+    // the implementation was done for cases that are known.
+    //
+    // If this method ever happens to act silly for your particular case then
+    // it is likely that it is a cause of not knowing about your case when it
+    // was implemented first. You are free to fix the behavior.
+    //
+    // Here are the assumptions that lead to the implementation:
+    // If direction is EAST increase the offset by one and ask the View to
+    // which that index belong to calculate the 'next visual position'.
+    // If the direction is WEST do the same with offset 'pos' being decreased
+    // by one.
+    // This behavior will fail in a right-to-left or bidi environment!
+    //
+    // This limitation is described as PR 27346.
+    int index;
+    
+    View v = null;
+    
+    switch (direction)
+    {
+      case EAST:
+        index = getViewIndex(pos + 1, b);
+        // If we cannot calculate a proper offset return the one that was
+        // provided.
+        if (index == -1)
+          return pos;
+        
+        v  = getView(index);
+        break;
+      case WEST:
+        index = getViewIndex(pos - 1, b);
+        // If we cannot calculate a proper offset return the one that was
+        // provided.
+        if (index == -1)
+          return pos;
+        
+        v  = getView(index);
+        break;
+      default:
+        throw new IllegalArgumentException();
+    }
+    
+    return v.getNextVisualPositionFrom(pos,
+                                       b,
+                                       a,
+                                       direction,
+                                       biasRet);
   }
 
   /**

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to