001: package gnu.kawa.swingviews;
002:
003: import javax.swing.text.*;
004: import javax.swing.undo.*;
005: import gnu.lists.*;
006:
007: /** A wrapper around a CharBuffer that implements Swing's Content.
008: * This allows us to use a CharBuffer for a Document's Content. */
009:
010: public class SwingContent implements
011: javax.swing.text.AbstractDocument.Content {
012: public final CharBuffer buffer;
013:
014: public SwingContent(CharBuffer buffer) {
015: this .buffer = buffer;
016: }
017:
018: public SwingContent(int initialSize) {
019: CharBuffer b = new CharBuffer(initialSize);
020: // Swing assumes that a Content object is initialized to contain
021: // a single '\n'. This of course is not clearly documented ...
022: b.gapEnd = initialSize - 1;
023: b.getArray()[b.gapEnd] = '\n';
024: this .buffer = b;
025: }
026:
027: public SwingContent() {
028: this (100);
029: }
030:
031: public int length() {
032: return buffer.length();
033: }
034:
035: public void getChars(int where, int len, Segment txt)
036: throws BadLocationException {
037: CharBuffer b = buffer;
038: int start = b.getSegment(where, len);
039: if (start < 0)
040: throw new BadLocationException("invalid offset", where);
041: txt.offset = start;
042: txt.array = b.getArray();
043: txt.count = len;
044: }
045:
046: public String getString(int where, int len)
047: throws BadLocationException {
048: CharBuffer b = buffer;
049: int start = b.getSegment(where, len);
050: if (start < 0)
051: throw new BadLocationException("invalid offset", where);
052: return new String(b.getArray(), start, len);
053: }
054:
055: public UndoableEdit remove(int where, int nitems)
056: throws BadLocationException {
057: CharBuffer b = buffer;
058: if (nitems < 0 || where < 0 || where + nitems > b.length())
059: throw new BadLocationException("invalid remove", where);
060:
061: b.delete(where, nitems);
062:
063: GapUndoableEdit undo = new GapUndoableEdit(where);
064: undo.content = this ;
065: undo.data = new String(b.getArray(), b.gapEnd - nitems, nitems);
066: undo.nitems = nitems;
067: undo.isInsertion = false;
068: return undo;
069: }
070:
071: public UndoableEdit insertString(int where, String str,
072: boolean beforeMarkers) throws BadLocationException {
073: CharBuffer b = buffer;
074: if (where < 0 || where > b.length())
075: throw new BadLocationException("bad insert", where);
076: b.insert(where, str, beforeMarkers);
077:
078: GapUndoableEdit undo = new GapUndoableEdit(where);
079: undo.content = this ;
080: undo.data = str;
081: undo.nitems = str.length();
082: undo.isInsertion = true;
083: return undo;
084: }
085:
086: public UndoableEdit insertString(int where, String str)
087: throws BadLocationException {
088: return insertString(where, str, false);
089: }
090:
091: public javax.swing.text.Position createPosition(int offset)
092: throws BadLocationException {
093: CharBuffer b = buffer;
094: if (offset < 0 || offset > b.length())
095: throw new BadLocationException(
096: "bad offset to createPosition", offset);
097: return new GapPosition(b, offset);
098: }
099:
100: }
101:
102: class GapPosition extends SeqPosition implements
103: javax.swing.text.Position {
104: public GapPosition(CharBuffer content, int offset) {
105: super (content, offset, false);
106: }
107:
108: public int getOffset() {
109: return nextIndex();
110: }
111: }
112:
113: class GapUndoableEdit extends AbstractUndoableEdit {
114: // False if this is a remove (delete); true if an insertion.
115: boolean isInsertion;
116:
117: SwingContent content;
118:
119: String data;
120:
121: int startOffset;
122: int nitems;
123:
124: GapUndoableEdit(int offset) {
125: startOffset = offset;
126: }
127:
128: private void doit(boolean isInsertion) throws BadLocationException {
129: //int startOffset = content.positions[content.indexes[startIndex]];
130: if (isInsertion) {
131: // FIXME returns useless Undo
132: content.insertString(startOffset, data);
133: } else {
134: // FIXME returns useless Undo
135: content.remove(startOffset, nitems);
136: }
137: }
138:
139: public void undo() throws CannotUndoException {
140: super .undo();
141: try {
142: doit(!isInsertion);
143: } catch (BadLocationException ex) {
144: throw new CannotUndoException();
145: }
146: }
147:
148: public void redo() throws CannotUndoException {
149: super .redo();
150: try {
151: doit(isInsertion);
152: } catch (BadLocationException ex) {
153: throw new CannotRedoException();
154: }
155: }
156: }
|