aboutsummaryrefslogtreecommitdiff
path: root/libjava/javax
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2005-05-06 06:03:17 +0000
committerMichael Koch <mkoch@gcc.gnu.org>2005-05-06 06:03:17 +0000
commit9dc83af902a99a589dfb8c05c0f16e1a5bdf812d (patch)
tree247bf4981adfa1e88ee56d2f591e9288e3778b8c /libjava/javax
parent876f4e199c63fce3ae79bde6a0b76b8057836f62 (diff)
downloadgcc-9dc83af902a99a589dfb8c05c0f16e1a5bdf812d.zip
gcc-9dc83af902a99a589dfb8c05c0f16e1a5bdf812d.tar.gz
gcc-9dc83af902a99a589dfb8c05c0f16e1a5bdf812d.tar.bz2
2005-05-06 Roman Kennke <roman@kennke.org>
* javax/swing/text/PlainView.java (drawUnselectedText): Call Utilities.drawTabbedText() with correct offset parameter. * javax/swing/text/Utilities.java (drawTabbedText): Initilialize local variable pos correctly. 2005-05-06 Roman Kennke <roman@kennke.org> * javax/swing/text/AbstractDocument.java (LeafElement): Made start and end package private fields for effective reindexing. * javax/swing/text/PlainDocument.java (constructor): The field rootElement is always BranchElement, so we handle it as such. (removeUpdate): Rewritten reindexing for removeUpdate so that the actual removal is taken into account. 2005-05-06 Roman Kennke <roman@kennke.org> * javax/swing/text/GapContent.java: Removed debugging output stuff, which I accidentally left in. 2005-05-06 Roman Kennke <roman@kennke.org> * javax/swing/text/GapContent.java: Implemented a real GapContent. Only the public methods have been implemented so far and still no UndoableEdit support. From-SVN: r99300
Diffstat (limited to 'libjava/javax')
-rw-r--r--libjava/javax/swing/text/AbstractDocument.java4
-rw-r--r--libjava/javax/swing/text/GapContent.java227
-rw-r--r--libjava/javax/swing/text/PlainDocument.java42
-rw-r--r--libjava/javax/swing/text/PlainView.java2
-rw-r--r--libjava/javax/swing/text/Utilities.java2
5 files changed, 240 insertions, 37 deletions
diff --git a/libjava/javax/swing/text/AbstractDocument.java b/libjava/javax/swing/text/AbstractDocument.java
index 29be0ad..efeb85d 100644
--- a/libjava/javax/swing/text/AbstractDocument.java
+++ b/libjava/javax/swing/text/AbstractDocument.java
@@ -847,8 +847,8 @@ public abstract class AbstractDocument
public class LeafElement extends AbstractElement
{
private static final long serialVersionUID = 5115368706941283802L;
- private int start;
- private int end;
+ int start;
+ int end;
public LeafElement(Element parent, AttributeSet attributes, int start,
int end)
diff --git a/libjava/javax/swing/text/GapContent.java b/libjava/javax/swing/text/GapContent.java
index a22aeed..111617e 100644
--- a/libjava/javax/swing/text/GapContent.java
+++ b/libjava/javax/swing/text/GapContent.java
@@ -40,8 +40,6 @@ package javax.swing.text;
import java.io.Serializable;
-// too lazy to make a real gapcontent.
-// lets just use a stringbuffer instead.
import javax.swing.undo.UndoableEdit;
/**
@@ -53,20 +51,41 @@ import javax.swing.undo.UndoableEdit;
* has to be shifted around when the insertion point moves (then the gap also
* moves and one array copy is necessary) or when the gap is filled up and
* the buffer has to be enlarged.
+ *
+ * TODO: Implement UndoableEdit support stuff
*/
public class GapContent
implements AbstractDocument.Content, Serializable
{
private static final long serialVersionUID = 8374645204155842629L;
-
- StringBuffer buf = new StringBuffer();
+
+ /**
+ * This is the default buffer size and the amount of bytes that
+ * a buffer is extended if it is full.
+ */
+ static final int DEFAULT_BUFSIZE = 64;
+
+ /**
+ * The text buffer.
+ */
+ char[] buffer;
+
+ /**
+ * The index of the first character of the gap.
+ */
+ int gapStart;
+
+ /**
+ * The index of the character after the last character of the gap.
+ */
+ int gapEnd;
/**
* Creates a new GapContent object.
*/
public GapContent()
{
- this(10);
+ this(DEFAULT_BUFSIZE);
}
/**
@@ -76,30 +95,33 @@ public class GapContent
*/
public GapContent(int size)
{
- buf.append("\n");
+ buffer = (char[]) allocateArray(size);
+ gapStart = 0;
+ gapEnd = size - 1;
+ buffer[size - 1] = '\n';
}
/**
- * Creates and returns a mark at the specified position.
- *
- * @param offset the position at which to create the mark
+ * Allocates an array of the specified length that can then be used as
+ * buffer.
*
- * @return the create Position object for the mark
+ * @param size the size of the array to be allocated
*
- * @throws BadLocationException if the offset is not a valid position in
- * the buffer
+ * @return the allocated array
*/
- public Position createPosition(final int offset) throws BadLocationException
+ protected Object allocateArray(int size)
{
- return new Position()
- {
- int off = offset;
+ return new char[size];
+ }
- public int getOffset()
- {
- return off;
- }
- };
+ /**
+ * Returns the length of the allocated buffer array.
+ *
+ * @return the length of the allocated buffer array
+ */
+ protected int getArrayLength()
+ {
+ return buffer.length;
}
/**
@@ -109,7 +131,7 @@ public class GapContent
*/
public int length()
{
- return buf.length();
+ return buffer.length - (gapEnd - gapStart);
}
/**
@@ -127,7 +149,27 @@ public class GapContent
public UndoableEdit insertString(int where, String str)
throws BadLocationException
{
- buf.insert(where, str);
+ // check arguments
+ int length = length();
+ int strLen = str.length();
+
+ if (where >= length)
+ throw new BadLocationException("the where argument cannot be greater"
+ + " than the content length", where);
+
+ // check if the gap is big enough to hold the string
+ if ((gapEnd - gapStart) < strLen)
+ // make room for this string and some more
+ shiftEnd(strLen + DEFAULT_BUFSIZE);
+
+ // are we at the gap boundary?
+ if (where != gapStart)
+ shiftGap(where);
+
+ // now we can simple copy the string into the gap and adjust the
+ // gap boundaries
+ System.arraycopy(str.toCharArray(), 0, buffer, gapStart, strLen);
+ gapStart += strLen;
return null;
}
@@ -146,7 +188,23 @@ public class GapContent
public UndoableEdit remove(int where, int nitems)
throws BadLocationException
{
- buf.delete(where, where + nitems);
+ // check arguments
+ int length = length();
+
+ if (where >= length)
+ throw new BadLocationException("the where argument cannot be greater"
+ + " than the content length", where);
+ if ((where + nitems) > length)
+ throw new BadLocationException("where + nitems cannot be greater"
+ + " than the content length",
+ where + nitems);
+
+ // check if we are at the gap boundary
+ if (where != gapStart)
+ shiftGap(where);
+
+ // now we simply have to enlarge the gap
+ gapEnd += nitems;
return null;
}
@@ -161,12 +219,18 @@ public class GapContent
*/
public String getString(int where, int len) throws BadLocationException
{
- return buf.substring(where, where+len);
+ Segment seg = new Segment();
+ getChars(where, len, seg);
+ return new String(seg.array, seg.offset, seg.count);
}
/**
* Fetches a piece of content and stores it in a {@link Segment} object.
*
+ * If the requested piece of text spans the gap, the content is copied
+ * into a new array. If it doesn't then it is contiguous and the
+ * actual content store is returned.
+ *
* @param where the start location of the fragment
* @param len the length of the fragment
* @param txt the Segment object to store the fragment in
@@ -177,11 +241,116 @@ public class GapContent
public void getChars(int where, int len, Segment txt)
throws BadLocationException
{
- txt.array = new char[len];
+ // check arguments
+ int length = length();
+ if (where >= length)
+ throw new BadLocationException("the where argument cannot be greater"
+ + " than the content length", where);
+ if ((where + len) > length)
+ throw new BadLocationException("len plus where cannot be greater"
+ + " than the content length",
+ len + where);
- System.arraycopy(buf.toString().toCharArray(), where, txt.array, 0, len);
+ // check if requested segment is contiguous
+ if ((where < gapStart) && ((gapStart - where) < len))
+ {
+ // requested segment is not contiguous -> copy the pieces together
+ char[] copy = new char[len];
+ int lenFirst = gapStart - where; // the length of the first segment
+ System.arraycopy(buffer, where, copy, 0, lenFirst);
+ System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);
+ txt.array = copy;
+ txt.offset = 0;
+ txt.count = len;
+ }
+ else
+ {
+ // requested segment is contiguous -> we can simply return the
+ // actual content
+ txt.array = buffer;
+ if (where < gapStart)
+ txt.offset = where;
+ else
+ txt.offset = where + (gapEnd - gapStart);
+ txt.count = len;
+ }
+ }
- txt.count = len;
- txt.offset = 0;
+ /**
+ * Creates and returns a mark at the specified position.
+ *
+ * @param offset the position at which to create the mark
+ *
+ * @return the create Position object for the mark
+ *
+ * @throws BadLocationException if the offset is not a valid position in
+ * the buffer
+ */
+ public Position createPosition(final int offset) throws BadLocationException
+ {
+ return new Position()
+ {
+ int off = offset;
+
+ public int getOffset()
+ {
+ return off;
+ }
+ };
+ }
+
+ /**
+ * Enlarges the gap. This allocates a new bigger buffer array, copy the
+ * segment before the gap as it is and the segment after the gap at
+ * the end of the new buffer array. This does change the gapEnd mark
+ * but not the gapStart mark.
+ *
+ * @param newSize the new size of the gap
+ */
+ protected void shiftEnd(int newSize)
+ {
+ char[] newBuf = (char[]) allocateArray(length() + newSize);
+ System.arraycopy(buffer, 0, newBuf, 0, gapStart);
+ System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize,
+ buffer.length - gapEnd);
+ gapEnd = gapStart + newSize;
+ buffer = newBuf;
+ }
+
+ /**
+ * Shifts the gap to the specified position.
+ *
+ * @param newGapStart the new start position of the gap
+ */
+ protected void shiftGap(int newGapStart)
+ {
+ int newGapEnd = newGapStart + (gapEnd - gapStart);
+
+ if (newGapStart == gapStart)
+ return;
+ else if (newGapStart < gapStart)
+ {
+ System.arraycopy(buffer, newGapStart, buffer, newGapEnd,
+ gapStart - newGapStart);
+ gapStart = newGapStart;
+ gapEnd = newGapEnd;
+ }
+ else
+ {
+ System.arraycopy(buffer, gapEnd, buffer, gapStart,
+ newGapStart - gapStart);
+ gapStart = newGapStart;
+ gapEnd = newGapEnd;
+ }
+ }
+
+ /**
+ * Returns the allocated buffer array.
+ *
+ * @return the allocated buffer array
+ */
+ protected Object getArray()
+ {
+ return buffer;
}
}
diff --git a/libjava/javax/swing/text/PlainDocument.java b/libjava/javax/swing/text/PlainDocument.java
index 64e9c8a..3a44725 100644
--- a/libjava/javax/swing/text/PlainDocument.java
+++ b/libjava/javax/swing/text/PlainDocument.java
@@ -47,7 +47,7 @@ public class PlainDocument extends AbstractDocument
public static final String lineLimitAttribute = "lineLimit";
public static final String tabSizeAttribute = "tabSize";
- private Element rootElement;
+ private BranchElement rootElement;
private int tabSize;
public PlainDocument()
@@ -59,7 +59,7 @@ public class PlainDocument extends AbstractDocument
{
super(content);
tabSize = 8;
- rootElement = createDefaultRoot();
+ rootElement = (BranchElement) createDefaultRoot();
}
private void reindex()
@@ -114,9 +114,43 @@ public class PlainDocument extends AbstractDocument
protected void removeUpdate(DefaultDocumentEvent event)
{
- reindex();
-
super.removeUpdate(event);
+
+ int p0 = event.getOffset();
+ int p1 = event.getLength() + p0;
+ int len = event.getLength();
+
+ // check if we must collapse some elements
+ int i1 = rootElement.getElementIndex(p0);
+ int i2 = rootElement.getElementIndex(p1);
+ if (i1 != i2)
+ {
+ Element el1 = rootElement.getElement(i1);
+ Element el2 = rootElement.getElement(i2);
+ int start = el1.getStartOffset();
+ int end = el2.getEndOffset();
+ // collapse elements if the removal spans more than 1 line
+ Element newEl = createLeafElement(rootElement,
+ SimpleAttributeSet.EMPTY,
+ start, end - len);
+ rootElement.replace(start, end - start, new Element[]{ newEl });
+ }
+ else
+ {
+ // otherwise only adjust indices of the element
+ LeafElement el1 = (LeafElement) rootElement.getElement(i1);
+ el1.end -= len;
+ }
+
+ // reindex remaining elements
+ for (int i = rootElement.getElementIndex(p0) + 1;
+ i < rootElement.getElementCount(); i++)
+ {
+ LeafElement el = (LeafElement) rootElement.getElement(i);
+ el.start -= len;
+ el.end -= len;
+ }
+
}
public Element getDefaultRootElement()
diff --git a/libjava/javax/swing/text/PlainView.java b/libjava/javax/swing/text/PlainView.java
index c852c1d..fb6af4e 100644
--- a/libjava/javax/swing/text/PlainView.java
+++ b/libjava/javax/swing/text/PlainView.java
@@ -148,7 +148,7 @@ public class PlainView extends View
g.setColor(unselectedColor);
Segment segment = new Segment();
getDocument().getText(p0, p1 - p0, segment);
- return Utilities.drawTabbedText(segment, x, y, g, this, 0);
+ return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset);
}
public void paint(Graphics g, Shape s)
diff --git a/libjava/javax/swing/text/Utilities.java b/libjava/javax/swing/text/Utilities.java
index c55f48e..7904701 100644
--- a/libjava/javax/swing/text/Utilities.java
+++ b/libjava/javax/swing/text/Utilities.java
@@ -92,7 +92,7 @@ public class Utilities
int ascent = metrics.getAscent();
int pixelWidth = 0;
- int pos = 0;
+ int pos = s.offset;
int len = 0;
for (int offset = s.offset; offset < (s.offset + s.count); ++offset)