KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > MarkChain


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.editor;
21
22 import javax.swing.text.BadLocationException JavaDoc;
23 import javax.swing.text.Document JavaDoc;
24 import javax.swing.text.Position JavaDoc;
25
26 /**
27 * Support class for chain of MarkBlocks
28 *
29 * @author Miloslav Metelka
30 * @version 1.00
31 */

32
33 public class MarkChain {
34
35     /** Chain of all marks */
36     protected MarkFactory.ChainDrawMark chain;
37
38     /** Current mark to make checks faster */
39     protected MarkFactory.ChainDrawMark curMark;
40
41     /** Document for this mark */
42     protected BaseDocument doc;
43
44     /** If this chain uses draw marks, then this is the name for the draw layer
45     * that will be used for the marks
46     */

47     protected String JavaDoc layerName;
48
49     /** The mark created by addMark() method is stored in this variable. In case
50      * the mark was not created, because there already was some on this position,
51      * the already existing mark is returned. */

52     private MarkFactory.ChainDrawMark recentlyAddedMark;
53     
54     /** Construct chain using draw marks */
55     public MarkChain(BaseDocument doc, String JavaDoc layerName) {
56         this.doc = doc;
57         this.layerName = layerName;
58     }
59
60     public final MarkFactory.ChainDrawMark getChain() {
61         return chain;
62     }
63
64     public final MarkFactory.ChainDrawMark getCurMark() {
65         return curMark;
66     }
67
68     /** Tests whether the position range is partly or fully inside
69     * some mark block from the chain.
70     * @param pos compared position
71     * @return relation of curMark to the given position
72     */

73     public int compareMark(int pos) {
74         try {
75             if (curMark == null) {
76                 curMark = chain;
77                 if (curMark == null) {
78                     return -1; // no marks yet
79
}
80             }
81
82             int rel;
83             boolean after = false;
84             boolean before = false;
85             while ((rel = curMark.compare(pos)) != 0) { // just match
86
if (rel > 0) { // this mark after pos
87
if (before) {
88                         return rel;
89                     }
90                     if (curMark.prev != null) {
91                         after = true;
92                         curMark = curMark.prev;
93                     } else { // end of chain
94
return rel;
95                     }
96                 } else { // this mark before pos
97
if (after) {
98                         return rel;
99                     }
100                     if (curMark.next != null) {
101                         before = true;
102                         curMark = curMark.next;
103                     } else { // start of chain
104
return rel;
105                     }
106                 }
107             }
108             return 0; // match
109
} catch (InvalidMarkException e) {
110             Utilities.annotateLoggable(e);
111             return -1; // don't match, but what to return?
112
}
113     }
114
115     protected MarkFactory.ChainDrawMark createAndInsertNewMark(int pos)
116     throws BadLocationException JavaDoc {
117         MarkFactory.ChainDrawMark mark = createMark();
118         try {
119             mark.insert(doc, pos);
120         } catch (InvalidMarkException e) {
121             Utilities.annotateLoggable(e);
122         }
123         return mark;
124     }
125
126     protected MarkFactory.ChainDrawMark createMark() {
127         MarkFactory.ChainDrawMark mark = new MarkFactory.ChainDrawMark(layerName, null, Position.Bias.Backward);
128         mark.activateLayer = true;
129         return mark;
130     }
131
132     public boolean addMark(int pos) throws BadLocationException JavaDoc {
133         return addMark(pos, false);
134     }
135
136     /** Add mark to the chain
137      * @param pos position at which the mark should be added
138      * @param forceAdd force adding of a fresh mark
139      * even if the mark at the same position already exists
140      * @return true if the mark was added
141      * false if there's already mark at that pos
142      */

143     public boolean addMark(int pos, boolean forceAdd) throws BadLocationException JavaDoc {
144         int rel = compareMark(pos);
145         if (rel == 0) {
146             if (forceAdd) { // create fresh
147
MarkFactory.ChainDrawMark mark = createAndInsertNewMark(pos);
148                 recentlyAddedMark = mark;
149                 if (curMark == chain) { // curMark is first mark
150
chain = curMark.insertChain(mark);
151                 } else { // curMark is not first mark
152
curMark.insertChain(mark);
153                 }
154                 
155             } else { // return existing
156
recentlyAddedMark = curMark;
157                 return false; // already exists
158
}
159
160         } else if (rel > 0) { // curMark after pos
161
MarkFactory.ChainDrawMark mark = createAndInsertNewMark(pos);
162             recentlyAddedMark = mark;
163             if (curMark != null) {
164                 if (curMark == chain) { // curMark is first mark
165
chain = curMark.insertChain(mark);
166                 } else { // curMark is not first mark
167
curMark.insertChain(mark);
168                 }
169             } else { // no marks in chain
170
chain = mark;
171             }
172         } else { // curMark before pos
173
MarkFactory.ChainDrawMark mark = createAndInsertNewMark(pos);
174             recentlyAddedMark = mark;
175             if (curMark != null) {
176                 if (curMark.next != null) {
177                     curMark.next.insertChain(mark);
178                 } else { // last mark in chain
179
curMark.setNextChain(mark);
180                 }
181             } else { // no marks in chain
182
chain = mark;
183             }
184         }
185         return true;
186     }
187
188     /** The mark created by addMark() method is returned by this method. In case
189      * the mark was not created, because there already was some on requested position,
190      * the already existing mark is returned. */

191     public MarkFactory.ChainDrawMark getAddedMark() {
192         return recentlyAddedMark;
193     }
194     
195     /** Remove non-empty block from area covered by blocks from chain */
196     public boolean removeMark(int pos) {
197         int rel = compareMark(pos);
198         if (rel == 0) {
199             boolean first = (curMark == chain);
200             curMark = curMark.removeChain();
201             if (first) {
202                 chain = curMark;
203             }
204             return true;
205         } else { // not found
206
return false;
207         }
208     }
209     
210     public boolean removeMark(MarkFactory.ChainDrawMark mark) {
211         if (mark == null) {
212             throw new NullPointerException JavaDoc();
213         }
214         
215         if (curMark != mark) {
216             // dumb impl
217
curMark = chain;
218             while (curMark != null) {
219                 if (curMark == mark) {
220                     break;
221                 }
222                 curMark = curMark.next;
223             }
224         }
225         
226         if (curMark != null) {
227             boolean first = (curMark == chain);
228             curMark = curMark.removeChain();
229             if (first) {
230                 chain = curMark;
231             }
232             return true;
233         } else {
234             return false;
235         }
236     }
237
238     /** Is there mark at given position? */
239     public boolean isMark(int pos) {
240         return (compareMark(pos) == 0);
241     }
242
243     /** Toggle the mark so that if it didn't exist it is created
244     * and if it existed it's removed
245     * @return true if the new mark was added
246     * false if the existing mark was removed
247     */

248     public boolean toggleMark(int pos) throws BadLocationException JavaDoc {
249         int rel = compareMark(pos);
250         if (rel == 0) { // exists
251
removeMark(pos);
252             return false;
253         } else { // didn't exist
254
addMark(pos);
255             return true;
256         }
257     }
258
259
260     public String JavaDoc toString() {
261         return "MarkChain: curMark=" + curMark + ", mark chain: " // NOI18N
262
+ (chain != null ? ("\n" + chain.toStringChain()) : "Empty"); // NOI18N
263
}
264
265 }
266
Popular Tags