001: /*
002: * Copyright (c) 2001, Jacob Smullyan.
003: *
004: * This is part of SkunkDAV, a WebDAV client. See http://skunkdav.sourceforge.net/
005: * for the latest version.
006: *
007: * SkunkDAV is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License as published
009: * by the Free Software Foundation; either version 2, or (at your option)
010: * any later version.
011: *
012: * SkunkDAV is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with SkunkDAV; see the file COPYING. If not, write to the Free
019: * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
020: * 02111-1307, USA.
021: */
022:
023: package org.skunk.swing.text.syntax;
024:
025: import javax.swing.text.BadLocationException;
026: import javax.swing.text.GapContent;
027: import javax.swing.undo.UndoableEdit;
028: import org.skunk.trace.Debug;
029: import org.skunk.util.GappedIntArray;
030:
031: public class SyntaxContent extends GapContent {
032: private GappedIntArray styleBuffer;
033: private SyntaxTokenizer syntaxTokenizer;
034: private FileMode fileMode;
035: private boolean isTokenizing;
036: private SyntaxDocument syntaxDocument;
037:
038: /**
039: * constructs a new SyntaxContent object, with a Flexicizer SyntaxTokenizer.
040: */
041: public SyntaxContent() {
042: super ();
043: this .styleBuffer = new GappedIntArray();
044: this .syntaxTokenizer = new Flexicizer();
045: }
046:
047: /**
048: * constructs a new SyntaxContent object with the given initial length.
049: * @param initialLength the initial length
050: */
051: public SyntaxContent(int initialLength) {
052: super (initialLength);
053: this .styleBuffer = new GappedIntArray();
054: this .syntaxTokenizer = new Flexicizer();
055: }
056:
057: /**
058: * constructs a new SyntaxContent object with the given SyntaxTokenizer.
059: * @param tokenizer the SyntaxTokenizer to install
060: */
061: public SyntaxContent(SyntaxTokenizer tokenizer) {
062: super ();
063: this .styleBuffer = new GappedIntArray();
064: this .syntaxTokenizer = tokenizer;
065: }
066:
067: /**
068: * gives access to the style buffer
069: */
070: public GappedIntArray getStyleBuffer() {
071: return styleBuffer;
072: }
073:
074: /**
075: * gives access to the syntax tokenizer
076: */
077: public SyntaxTokenizer getSyntaxTokenizer() {
078: return syntaxTokenizer;
079: }
080:
081: /**
082: * applies a syntax tokenizer.
083: * @param syntaxTokenizer the tokenizer
084: */
085: public void setSyntaxTokenizer(SyntaxTokenizer syntaxTokenizer) {
086: this .syntaxTokenizer = syntaxTokenizer;
087: }
088:
089: /**
090: * gives the content object a reference to the document.
091: * A hack, but it needs this at present to call the tokenizer's
092: * tokenize() method.
093: * @param syntaxDocument the SyntaxDocument which owns this content object
094: */
095: protected void setSyntaxDocument(SyntaxDocument syntaxDocument) {
096: this .syntaxDocument = syntaxDocument;
097: }
098:
099: /**
100: * sets the file mode.
101: * @param mode the file mode
102: */
103: public void setFileMode(FileMode mode) {
104: this .fileMode = mode;
105: this .isTokenizing = mode.getShouldHighlight();
106: }
107:
108: /**
109: * returns the file mode of this tokenizer.
110: * @return the file mode, or null if the tokenizer currently has no mode
111: */
112: public FileMode getFileMode() {
113: return fileMode;
114: }
115:
116: /**
117: * says whether tokenization is on.
118: * If it returns true, the syntaxDocument and syntaxTokenizer must both be non-null
119: * @return whether tokenization is on.
120: */
121: public boolean isTokenizing() {
122: return (syntaxDocument != null && syntaxTokenizer != null && this .isTokenizing);
123: }
124:
125: /**
126: * sets tokenization on.
127: * If there is no tokenizer installed, or if the syntaxDocument is null,
128: * isTokenizing() will return false, regardless of the value set here.
129: * @param tokenizing whether to tokenize
130: */
131: public void setTokenizing(boolean tokenizing) {
132: this .isTokenizing = tokenizing;
133: }
134:
135: /**
136: * insert string into the content at the given offset.
137: * overridden to allocate space in the style buffer for the
138: * insert, and to tokenize the document.
139: * @param where the offset into the document where the insert should begin
140: * @param str the string to insert
141: * @exception BadLocationException if the offset is greater than the document length
142: */
143: public UndoableEdit insertString(int where, String str)
144: throws BadLocationException {
145: if (Debug.DEBUG)
146: Debug.trace(this , Debug.DP4, "in insertString({0}, {1})",
147: new Object[] { new Integer(where), str });
148: int growth = str.length();
149: int[] tmp = new int[growth];
150: for (int i = 0; i < growth; i++)
151: tmp[i] = SyntaxStyle.UNFINISHED;
152: styleBuffer.insertAt(where, tmp);
153: UndoableEdit edit = super .insertString(where, str);
154: if (isTokenizing()) {
155: synchronized (styleBuffer) {
156: getSyntaxTokenizer().tokenize(syntaxDocument, where,
157: growth, 0);
158: }
159: }
160: return edit;
161: }
162:
163: /**
164: * removes characters from the content.
165: * overridden to deallocate space from the styleBuffer,
166: * and to tokenize the document.
167: * @param where the offset of the removal
168: * @param nitems the number of characters to remove
169: * @exception BadLocationException if the parameters are out of bounds
170: */
171: public UndoableEdit remove(int where, int nitems)
172: throws BadLocationException {
173: if (Debug.DEBUG)
174: Debug.trace(this , Debug.DP4, "in remove({0}, {1})",
175: new Object[] { new Integer(where),
176: new Integer(nitems) });
177: styleBuffer.remove(where, nitems);
178: UndoableEdit edit = super .remove(where, nitems);
179: if (isTokenizing()) {
180: synchronized (styleBuffer) {
181: getSyntaxTokenizer().tokenize(syntaxDocument, where, 0,
182: nitems);
183: }
184: }
185: return edit;
186: }
187: }
|