001: /*
002: * SyntaxDocument.java - Document that can be tokenized
003: * Copyright (C) 1999 Slava Pestov
004: *
005: * You may use and modify this package for any purpose. Redistribution is
006: * permitted, in both source and binary form, provided that this notice
007: * remains intact in all source distributions of this package.
008: */
009:
010: package org.syntax.jedit;
011:
012: import java.awt.Color;
013:
014: import javax.swing.event.DocumentEvent;
015: import javax.swing.text.*;
016: import javax.swing.undo.UndoableEdit;
017:
018: import org.syntax.jedit.tokenmarker.TokenMarker;
019:
020: /**
021: * A document implementation that can be tokenized by the syntax highlighting
022: * system.
023: *
024: * @author Slava Pestov
025: * @version $Id: SyntaxDocument.java 3074 2004-11-08 04:24:58Z bquig $
026: */
027: public class SyntaxDocument extends PlainDocument {
028: // private members
029: protected Color[] colors;
030:
031: /**
032: * Creates a new <code>DefaultSyntaxDocument</code> instance.
033: */
034: public SyntaxDocument(Color[] colors) {
035: this .colors = colors;
036: //addDocumentListener(new DocumentHandler());
037: }
038:
039: /**
040: * Returns the token marker that is to be used to split lines
041: * of this document up into tokens. May return null if this
042: * document is not to be colorized.
043: */
044: public TokenMarker getTokenMarker() {
045: return tokenMarker;
046: }
047:
048: /**
049: * Returns the color array that maps token identifiers to
050: * <code>java.awt.Color</code> objects.
051: */
052: public Color[] getColors() {
053: return colors;
054: }
055:
056: /**
057: * Sets the token marker that is to be used to split lines of
058: * this document up into tokens. May throw an exception if
059: * this is not supported for this type of document.
060: * @param tm The new token marker
061: */
062: public void setTokenMarker(TokenMarker tm) {
063: tokenMarker = tm;
064: if (tm == null)
065: return;
066: tokenMarker.insertLines(0, getDefaultRootElement()
067: .getElementCount());
068: tokenizeLines();
069: }
070:
071: /**
072: * Reparses the document, by passing all lines to the token
073: * marker. This should be called after the document is first
074: * loaded.
075: */
076: public void tokenizeLines() {
077: tokenizeLines(0, getDefaultRootElement().getElementCount());
078: }
079:
080: /**
081: * Reparses the document, by passing the specified lines to the
082: * token marker. This should be called after a large quantity of
083: * text is first inserted.
084: * @param start The first line to parse
085: * @param len The number of lines, after the first one to parse
086: */
087: public void tokenizeLines(int start, int len) {
088: if (tokenMarker == null
089: || !tokenMarker.supportsMultilineTokens())
090: return;
091:
092: Segment lineSegment = new Segment();
093: Element map = getDefaultRootElement();
094:
095: len += start;
096:
097: try {
098: for (int i = start; i < len; i++) {
099: Element lineElement = map.getElement(i);
100: int lineStart = lineElement.getStartOffset();
101: getText(lineStart, lineElement.getEndOffset()
102: - lineStart - 1, lineSegment);
103: tokenMarker.markTokens(lineSegment, i);
104: }
105: } catch (BadLocationException bl) {
106: bl.printStackTrace();
107: }
108: }
109:
110: /**
111: * Starts a compound edit that can be undone in one operation.
112: * Subclasses that implement undo should override this method;
113: * this class has no undo functionality so this method is
114: * empty.
115: */
116: public void beginCompoundEdit() {
117: }
118:
119: /**
120: * Ends a compound edit that can be undone in one operation.
121: * Subclasses that implement undo should override this method;
122: * this class has no undo functionality so this method is
123: * empty.
124: */
125: public void endCompoundEdit() {
126: }
127:
128: /**
129: * Adds an undoable edit to this document's undo list. The edit
130: * should be ignored if something is currently being undone.
131: * @param edit The undoable edit
132: *
133: * @since jEdit 2.2pre1
134: */
135: public void addUndoableEdit(UndoableEdit edit) {
136: }
137:
138: // protected members
139: protected TokenMarker tokenMarker;
140:
141: /**
142: * We overwrite this method to update the token marker
143: * state immediately so that any event listeners get a
144: * consistent token marker.
145: */
146: protected void fireInsertUpdate(DocumentEvent evt) {
147: if (tokenMarker != null) {
148: DocumentEvent.ElementChange ch = evt
149: .getChange(getDefaultRootElement());
150: if (ch != null) {
151: tokenMarker.insertLines(ch.getIndex() + 1, ch
152: .getChildrenAdded().length
153: - ch.getChildrenRemoved().length);
154: }
155: }
156:
157: super .fireInsertUpdate(evt);
158: }
159:
160: /**
161: * We overwrite this method to update the token marker
162: * state immediately so that any event listeners get a
163: * consistent token marker.
164: */
165: protected void fireRemoveUpdate(DocumentEvent evt) {
166: if (tokenMarker != null) {
167: DocumentEvent.ElementChange ch = evt
168: .getChange(getDefaultRootElement());
169: if (ch != null) {
170: tokenMarker.deleteLines(ch.getIndex() + 1, ch
171: .getChildrenRemoved().length
172: - ch.getChildrenAdded().length);
173: }
174: }
175:
176: super.fireRemoveUpdate(evt);
177: }
178: }
|