1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49:
50:
57: public final class StringContent
58: implements AbstractDocument.Content, Serializable
59: {
60:
61: private static final long serialVersionUID = 4755994433709540381L;
62:
63:
64: char[] content;
65:
66: private int count;
67:
68: private Vector positions = new Vector();
69:
70: private class InsertUndo extends AbstractUndoableEdit
71: {
72: private int start;
73:
74: private int length;
75:
76: private String redoContent;
77:
78: public InsertUndo(int start, int length)
79: {
80: super();
81: this.start = start;
82: this.length = length;
83: }
84:
85: public void undo()
86: {
87: super.undo();
88: try
89: {
90: StringContent.this.checkLocation(this.start, this.length);
91: this.redoContent = new String(StringContent.this.content, this.start,
92: this.length);
93: StringContent.this.remove(this.start, this.length);
94: }
95: catch (BadLocationException b)
96: {
97: throw new CannotUndoException();
98: }
99: }
100:
101: public void redo()
102: {
103: super.redo();
104: try
105: {
106: StringContent.this.insertString(this.start, this.redoContent);
107: }
108: catch (BadLocationException b)
109: {
110: throw new CannotRedoException();
111: }
112: }
113: }
114:
115: private class RemoveUndo extends AbstractUndoableEdit
116: {
117: private int start;
118:
119: private String undoString;
120:
121: public RemoveUndo(int start, String str)
122: {
123: super();
124: this.start = start;
125: this.undoString = str;
126: }
127:
128: public void undo()
129: {
130: super.undo();
131: try
132: {
133: StringContent.this.insertString(this.start, this.undoString);
134: }
135: catch (BadLocationException bad)
136: {
137: throw new CannotUndoException();
138: }
139: }
140:
141: public void redo()
142: {
143: super.redo();
144: try
145: {
146: int end = this.undoString.length();
147: StringContent.this.remove(this.start, end);
148: }
149: catch (BadLocationException bad)
150: {
151: throw new CannotRedoException();
152: }
153: }
154: }
155:
156: private class StickyPosition implements Position
157: {
158: private int offset = -1;
159:
160: public StickyPosition(int offset)
161: {
162: this.offset = offset;
163: }
164:
165:
166: void setOffset(int offset)
167: {
168: this.offset = this.offset >= 0 ? offset : -1;
169: }
170:
171:
174: public int getOffset()
175: {
176: return offset < 0 ? 0 : offset;
177: }
178: }
179:
180:
183: public StringContent()
184: {
185: this(1);
186: }
187:
188:
194: public StringContent(int initialLength)
195: {
196: super();
197: if (initialLength < 1)
198: initialLength = 1;
199: this.content = new char[initialLength];
200: this.content[0] = '\n';
201: this.count = 1;
202: }
203:
204: protected Vector getPositionsInRange(Vector v,
205: int offset,
206: int length)
207: {
208: Vector refPos = new Vector();
209: Iterator iter = this.positions.iterator();
210: while(iter.hasNext())
211: {
212: Position p = (Position) iter.next();
213: if ((offset <= p.getOffset())
214: && (p.getOffset() <= (offset + length)))
215: refPos.add(p);
216: }
217: return refPos;
218: }
219:
220:
230: public Position createPosition(int offset) throws BadLocationException
231: {
232: if (offset < this.count || offset > this.count)
233: checkLocation(offset, 0);
234: StickyPosition sp = new StickyPosition(offset);
235: this.positions.add(sp);
236: return sp;
237: }
238:
239:
245: public int length()
246: {
247: return this.count;
248: }
249:
250:
260: public UndoableEdit insertString(int where, String str)
261: throws BadLocationException
262: {
263: checkLocation(where, 0);
264: if (where == this.count)
265: throw new BadLocationException("Invalid location", 1);
266: if (str == null)
267: throw new NullPointerException();
268: char[] insert = str.toCharArray();
269: char[] temp = new char[this.content.length + insert.length];
270: this.count += insert.length;
271:
272: if (where > 0)
273: System.arraycopy(this.content, 0, temp, 0, where);
274: System.arraycopy(insert, 0, temp, where, insert.length);
275: System.arraycopy(this.content, where, temp, (where + insert.length),
276: (temp.length - where - insert.length));
277: if (this.content.length < temp.length)
278: this.content = new char[temp.length];
279:
280: System.arraycopy(temp, 0, this.content, 0, temp.length);
281:
282: Vector refPos = getPositionsInRange(this.positions, where,
283: temp.length - where);
284: Iterator iter = refPos.iterator();
285: while (iter.hasNext())
286: {
287: StickyPosition p = (StickyPosition)iter.next();
288: p.setOffset(p.getOffset() + str.length());
289: }
290: InsertUndo iundo = new InsertUndo(where, insert.length);
291: return iundo;
292: }
293:
294:
306: public UndoableEdit remove(int where, int nitems) throws BadLocationException
307: {
308: checkLocation(where, nitems + 1);
309: char[] temp = new char[(this.content.length - nitems)];
310: this.count = this.count - nitems;
311: RemoveUndo rundo = new RemoveUndo(where, new String(this.content, where,
312: nitems));
313:
314: System.arraycopy(this.content, 0, temp, 0, where);
315: System.arraycopy(this.content, where + nitems, temp, where,
316: this.content.length - where - nitems);
317: this.content = new char[temp.length];
318:
319: System.arraycopy(temp, 0, this.content, 0, this.content.length);
320:
321: Vector refPos = getPositionsInRange(this.positions, where,
322: this.content.length + nitems - where);
323: Iterator iter = refPos.iterator();
324: while (iter.hasNext())
325: {
326: StickyPosition p = (StickyPosition)iter.next();
327: int result = p.getOffset() - nitems;
328: p.setOffset(result);
329: if (result < 0)
330: this.positions.remove(p);
331: }
332: return rundo;
333: }
334:
335:
347: public String getString(int where, int len) throws BadLocationException
348: {
349: checkLocation(where, len);
350: return new String(this.content, where, len);
351: }
352:
353:
366: public void getChars(int where, int len, Segment txt)
367: throws BadLocationException
368: {
369: checkLocation(where, len);
370: txt.array = this.content;
371: txt.offset = where;
372: txt.count = len;
373: }
374:
375:
376:
382: protected void updateUndoPositions(Vector positions)
383: {
384:
385: }
386:
387:
397: void checkLocation(int where, int len) throws BadLocationException
398: {
399: if (where < 0)
400: throw new BadLocationException("Invalid location", 1);
401: else if (where > this.count)
402: throw new BadLocationException("Invalid location", this.count);
403: else if ((where + len) > this.count)
404: throw new BadLocationException("Invalid range", this.count);
405: }
406:
407: }