Here are some general fixes I made (and committed tests for) for the
text package while I was trying to correct DefaultStyledDocument's
behaviour.

2006-01-05  Anthony Balkissoon  <[EMAIL PROTECTED]>

        * javax/swing/JTextPane.java:
        (replaceSelection): If the document is an AbstractDocument, use replace
        rather than remove and insert.
        * javax/swing/event/EventListenerList.java:
        (getListeners): Reversed the order of the listeners to match the 
        reference implementation.
        * javax/swing/text/AbstractDocument.java:
        (insertString): Add the UndoableEdit from the content.insertString call
        to the DocumentEvent.
        (DefaultDocumentEvent.toString): Implemented.
        * javax/swing/text/DefaultCaret.java:
        (setDot): Make sure dot is > 0 and less than the length of the 
        document.
        * javax/swing/text/DefaultStyledDocument.java:
        (ElementBuffer.insertUpdate): Set the modified tag of the document 
        event when we get start and end tags.  This ensures that we create the
        proper BranchElements in endEdit().
        (ElementBuffer.insertUpdate): Added FIXME to handle 
        JoinFractureDirection case.
        (insertUpdate): Added code to check if we're inserting immediately 
        after a newline and to handle this case (create start and end tags). 
        Only change the direction of the first and last tags if they are of 
        type ContentType.
        (checkForInsertAfterNewline): New helper method.
        (handleInsertAfterNewline): Likewise.
        * javax/swing/text/View.java:
        (updateLayout): Avoid NPE by checking if shape is null.  Repaint 
        container.

--Tony
? include/gnu_java_net_PlainDatagramSocketImpl.h
? include/gnu_java_net_PlainSocketImpl.h
Index: javax/swing/JTextPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JTextPane.java,v
retrieving revision 1.13
diff -u -r1.13 JTextPane.java
--- javax/swing/JTextPane.java	17 Nov 2005 21:42:48 -0000	1.13
+++ javax/swing/JTextPane.java	5 Jan 2006 20:13:57 -0000
@@ -40,6 +40,7 @@
 
 import java.awt.Component;
 
+import javax.swing.text.AbstractDocument;
 import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Caret;
@@ -151,38 +152,34 @@
   {
     Caret caret = getCaret();
     StyledDocument doc = getStyledDocument();
+    AttributeSet a = getInputAttributes().copyAttributes();
+    if (doc == null)
+      return;
 
     int dot = caret.getDot();
     int mark = caret.getMark();
 
-    // If content is empty delete selection.
-    if (content == null)
-      {
-	caret.setDot(dot);
-	return;
-      }
+    int p0 = Math.min (dot, mark);
+    int p1 = Math.max (dot, mark);
 
     try
       {
-	int start = getSelectionStart();
-	int end = getSelectionEnd();
-	int contentLength = content.length();
-
-	// Remove selected text.
-	if (dot != mark)
-	  doc.remove(start, end - start);
-
-	// Insert new text.
-	doc.insertString(start, content, null);
-	// Set attributes for inserted text
-	doc.setCharacterAttributes(start, contentLength, getInputAttributes(),
-				   true);
-
+        if (doc instanceof AbstractDocument)
+          ((AbstractDocument)doc).replace(p0, p1 - p0, content, a);
+        else
+          {
+            // Remove selected text.
+            if (dot != mark)
+              doc.remove(p0, p1 - p0);
+            // Insert new text.
+            if (content != null && content.length() > 0)
+              doc.insertString(p0, content, a);
+          }
       }
     catch (BadLocationException e)
       {
-	throw new AssertionError
-	  ("No BadLocationException should be thrown here");
+        throw new AssertionError
+          ("No BadLocationException should be thrown here");      
       }
   }
 
Index: javax/swing/event/EventListenerList.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/event/EventListenerList.java,v
retrieving revision 1.13
diff -u -r1.13 EventListenerList.java
--- javax/swing/event/EventListenerList.java	18 Oct 2005 20:38:05 -0000	1.13
+++ javax/swing/event/EventListenerList.java	5 Jan 2006 20:13:57 -0000
@@ -228,7 +228,7 @@
     count = getListenerCount(c);
     result = (EventListener[]) Array.newInstance(c, count);
     f = 0;
-    for (int i = 0; i < listenerList.length; i += 2)
+    for (int i = listenerList.length - 2; i >= 0; i -= 2)
       if (listenerList[i] == c)
         result[f++] = (EventListener) listenerList[i + 1];
     
Index: javax/swing/text/AbstractDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v
retrieving revision 1.42
diff -u -r1.42 AbstractDocument.java
--- javax/swing/text/AbstractDocument.java	20 Dec 2005 21:28:16 -0000	1.42
+++ javax/swing/text/AbstractDocument.java	5 Jan 2006 20:13:58 -0000
@@ -541,6 +541,9 @@
     
     writeLock();
     UndoableEdit undo = content.insertString(offset, text);
+    if (undo != null)
+      event.addEdit(undo);
+
     insertUpdate(event, attributes);
     writeUnlock();
 
@@ -1911,6 +1914,15 @@
       // XXX - Fully qualify ElementChange to work around gcj bug #2499.
       return (DocumentEvent.ElementChange) changes.get(elem);
     }
+    
+    /**
+     * Returns a String description of the change event.  This returns the
+     * toString method of the Vector of edits.
+     */
+    public String toString()
+    {
+      return edits.toString();
+    }
   }
   
   /**
Index: javax/swing/text/DefaultCaret.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v
retrieving revision 1.26
diff -u -r1.26 DefaultCaret.java
--- javax/swing/text/DefaultCaret.java	22 Nov 2005 16:10:27 -0000	1.26
+++ javax/swing/text/DefaultCaret.java	5 Jan 2006 20:13:58 -0000
@@ -829,9 +829,12 @@
   public void setDot(int dot)
   {
     if (dot >= 0)
-      {
+      {        
+        Document doc = textComponent.getDocument();
+        if (doc != null)
+          this.dot = Math.min(dot, doc.getLength());
+        this.dot = Math.max(dot, 0);
         this.mark = dot;
-        this.dot = dot;
         handleHighlight();
         adjustVisibility(this);
         appear();
Index: javax/swing/text/DefaultStyledDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v
retrieving revision 1.25
diff -u -r1.25 DefaultStyledDocument.java
--- javax/swing/text/DefaultStyledDocument.java	3 Jan 2006 13:38:11 -0000	1.25
+++ javax/swing/text/DefaultStyledDocument.java	5 Jan 2006 20:13:58 -0000
@@ -789,9 +789,11 @@
             {
             case ElementSpec.StartTagType:
               numStartTags++;
+              documentEvent.modified = true;
               break;
             case ElementSpec.EndTagType:
               numEndTags++;
+              documentEvent.modified = true;
               break;
             default:
               insertContentTag(data[i]);
@@ -929,7 +931,11 @@
           // Add this action to the document event.
           addEdit(paragraph, currentIndex, remove, add);
         }
-      else
+      else if (dir == ElementSpec.JoinFractureDirection)
+        {
+          // TODO: What should be done here?
+        }
+      else if (dir == ElementSpec.OriginateDirection)
         {
           BranchElement paragraph = (BranchElement) elementStack.peek();
           int index = paragraph.getElementIndex(offset);
@@ -1564,7 +1570,7 @@
     int length = ev.getLength();
     int endOffset = offset + length;
     AttributeSet paragraphAttributes = 
-      getParagraphElement(endOffset).getAttributes();
+      getParagraphElement(endOffset).getAttributes();    
     Segment txt = new Segment();
     try
       {
@@ -1579,46 +1585,75 @@
 
     int len = 0;
     Vector specs = new Vector();
-
+    ElementSpec finalStartTag = null;
+    short finalStartDirection = ElementSpec.OriginateDirection;
+    boolean prevCharWasNewline = false;
     Element prev = getCharacterElement(offset);
-    Element next = getCharacterElement(endOffset);
+    Element next = getCharacterElement(endOffset);    
+    Element prevParagraph = getParagraphElement(offset);
+    Element paragraph = getParagraphElement(endOffset);
     
     int segmentEnd = txt.offset + txt.count;
+    
+    // Check to see if we're inserting immediately after a newline.
+    checkForInsertAfterNewline(offset, endOffset, prevParagraph, paragraph,
+                               paragraphAttributes, prevCharWasNewline,
+                               finalStartTag, finalStartDirection, specs);
+        
     for (int i = txt.offset; i < segmentEnd; ++i)
       {
         len++;
         if (txt.array[i] == '\n')
           {
-            ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType,
-                                               len);          
-            specs.add(spec);
+            // Add the ElementSpec for the content.
+            specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));            
 
             // Add ElementSpecs for the newline.
-            ElementSpec endTag = new ElementSpec(null, ElementSpec.EndTagType);
-            specs.add(endTag);
-            ElementSpec startTag = new ElementSpec(paragraphAttributes,
+            specs.add(new ElementSpec(null, ElementSpec.EndTagType));
+            finalStartTag = new ElementSpec(paragraphAttributes,
                                                    ElementSpec.StartTagType);
-            startTag.setDirection(ElementSpec.JoinFractureDirection);
-            specs.add(startTag);
-
+            specs.add(finalStartTag);
             len = 0;
           }
       }
 
     // Create last element if last character hasn't been a newline.
     if (len > 0)                      
-      specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));      
+      specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
 
+    // Set the direction of the last spec of type StartTagType.  
+    // If we are inserting after a newline then this value comes from 
+    // handleInsertAfterNewline.
+    if (finalStartTag != null)
+      {
+        if (prevCharWasNewline)
+          finalStartTag.setDirection(finalStartDirection);
+        else if (prevParagraph.getEndOffset() != endOffset)
+          finalStartTag.setDirection(ElementSpec.JoinFractureDirection);
+        else
+          {
+            // If there is an element AFTER this one, then set the 
+            // direction to JoinNextDirection.
+            Element parent = prevParagraph.getParentElement();
+            int index = parent.getElementIndex(offset);
+            if (index + 1 < parent.getElementCount()
+                && !parent.getElement(index + 1).isLeaf())
+              finalStartTag.setDirection(ElementSpec.JoinNextDirection);
+          }
+      }
+    
     // If we are at the last index, then check if we could probably be
     // joined with the next element.
-    ElementSpec last = (ElementSpec) specs.lastElement();
-    if (next.getAttributes().isEqual(attr))
+    ElementSpec last = (ElementSpec) specs.lastElement();        
+    if (next.getAttributes().isEqual(attr)
+        && last.getType() == ElementSpec.ContentType)
       last.setDirection(ElementSpec.JoinNextDirection);    
     
     // If we are at the first new element, then check if it could be
     // joined with the previous element.
     ElementSpec first = (ElementSpec) specs.firstElement();
-    if (prev.getAttributes().isEqual(attr))
+    if (prev.getAttributes().isEqual(attr)
+        && first.getType() == ElementSpec.ContentType)
       first.setDirection(ElementSpec.JoinPreviousDirection);
     
     ElementSpec[] elSpecs =
@@ -1628,6 +1663,73 @@
   }
 
   /**
+   * A helper method that checks to see if insertUpdate was called when text
+   * was inserted immediately after a newline, and calls 
+   * handleInsertAfterNewline if that is the case.
+   */
+  void checkForInsertAfterNewline(int offset, int endOffset,
+                                  Element prevParagraph, Element paragraph,
+                                  AttributeSet paragraphAttributes,
+                                  boolean prevCharWasNewline,
+                                  ElementSpec finalStartTag,
+                                  short finalStartDirection, Vector specs)
+  {
+    if (offset > 0)
+      {
+        try
+        {
+          String s = getText(offset - 1, 1);
+          if (s.equals("\n"))
+            {
+              finalStartDirection = 
+                handleInsertAfterNewline(specs, offset, endOffset,
+                                         prevParagraph,
+                                         paragraph,
+                                         paragraphAttributes);
+              
+              prevCharWasNewline = true;
+              // Find the final start tag from the ones just created.
+              for (int i = 0; i < specs.size(); i++)
+                if (((ElementSpec) specs.get(i)).getType() 
+                    == ElementSpec.StartTagType)
+                  finalStartTag = (ElementSpec)specs.get(i);
+            }
+        }
+        catch (BadLocationException ble)
+        {          
+          // This shouldn't happen.
+          AssertionError ae = new AssertionError();
+          ae.initCause(ble);
+          throw ae;
+        }        
+      }
+  }
+  
+  /**
+   * A helper method to set up the ElementSpec buffer for the special
+   * case of an insertion occurring immediately after a newline.
+   * @param specs the ElementSpec buffer to initialize.
+   */
+  short handleInsertAfterNewline(Vector specs, int offset, int endOffset,
+                                Element prevParagraph, Element paragraph,
+                                AttributeSet a)
+  {
+    if (prevParagraph.getParentElement() == paragraph.getParentElement())
+      {
+        specs.add(new ElementSpec(a, ElementSpec.EndTagType));
+        specs.add(new ElementSpec(a, ElementSpec.StartTagType));
+        if (prevParagraph.getEndOffset() != endOffset)
+          return ElementSpec.JoinFractureDirection;
+        
+      }
+    else
+      {
+        // TODO: What to do here?
+      }
+    return ElementSpec.OriginateDirection;
+  }
+  
+  /**
    * Updates the document structure in response to text removal. This is
    * forwarded to the [EMAIL PROTECTED] ElementBuffer} of this document. Any changes to
    * the document structure are added to the specified document event and
@@ -1671,7 +1773,22 @@
     else if (start instanceof AbstractDocument.BranchElement)
       System.out.println ("BranchElement ("+start.getStartOffset()+", "+start.getEndOffset()+")");
     else
-      System.out.println ("LeafElement ("+start.getStartOffset()+", "+start.getEndOffset()+")");
+      {
+        {
+          try
+            {
+              System.out.println ("LeafElement ("+start.getStartOffset()+", "
+                                  + start.getEndOffset()+"): "+ 
+                                  start.getDocument().
+                                  getText(start.getStartOffset(), 
+                                          start.getEndOffset() - 
+                                          start.getStartOffset()));
+            }
+          catch (BadLocationException ble)
+            {
+            }
+        }
+      }
     for (int i = 0; i < start.getElementCount(); i ++)
       printElements (start.getElement(i), pad+3);
   }
Index: javax/swing/text/View.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/View.java,v
retrieving revision 1.24
diff -u -r1.24 View.java
--- javax/swing/text/View.java	23 Nov 2005 11:59:30 -0000	1.24
+++ javax/swing/text/View.java	5 Jan 2006 20:13:58 -0000
@@ -447,9 +447,11 @@
   protected void updateLayout(DocumentEvent.ElementChange ec,
                               DocumentEvent ev, Shape shape)
   {
-    Rectangle b = shape.getBounds();
-    if (ec != null)
-      preferenceChanged(this, true, true);
+    if (ec != null && shape != null)
+      preferenceChanged(null, true, true);
+    Container c = getContainer();
+    if (c != null)
+      c.repaint();
   }
 
   /**
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to