Lines 1-877
Link Here
|
1 |
/* |
|
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. |
5 |
* |
6 |
* The contents of this file are subject to the terms of either the GNU |
7 |
* General Public License Version 2 only ("GPL") or the Common |
8 |
* Development and Distribution License("CDDL") (collectively, the |
9 |
* "License"). You may not use this file except in compliance with the |
10 |
* License. You can obtain a copy of the License at |
11 |
* http://www.netbeans.org/cddl-gplv2.html |
12 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
13 |
* specific language governing permissions and limitations under the |
14 |
* License. When distributing the software, include this License Header |
15 |
* Notice in each file and include the License file at |
16 |
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this |
17 |
* particular file as subject to the "Classpath" exception as provided |
18 |
* by Sun in the GPL Version 2 section of the License file that |
19 |
* accompanied this code. If applicable, add the following below the |
20 |
* License Header, with the fields enclosed by brackets [] replaced by |
21 |
* your own identifying information: |
22 |
* "Portions Copyrighted [year] [name of copyright owner]" |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* The Original Software is NetBeans. The Initial Developer of the Original |
27 |
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun |
28 |
* Microsystems, Inc. All Rights Reserved. |
29 |
* |
30 |
* If you wish your version of this file to be governed by only the CDDL |
31 |
* or only the GPL Version 2, indicate your decision by adding |
32 |
* "[Contributor] elects to include this software in this distribution |
33 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
34 |
* single choice of license, a recipient has the option to distribute |
35 |
* your version of this file under either the CDDL, the GPL Version 2 or |
36 |
* to extend the choice of license to its licensees as provided above. |
37 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
38 |
* Version 2 license, then the option applies only if the new code is |
39 |
* made subject to such option by the copyright holder. |
40 |
*/ |
41 |
|
42 |
package org.netbeans.editor; |
43 |
|
44 |
import java.awt.Color; |
45 |
import java.util.List; |
46 |
import java.util.logging.Level; |
47 |
import java.util.logging.Logger; |
48 |
import javax.swing.text.Style; |
49 |
import javax.swing.text.StyleConstants; |
50 |
import javax.swing.text.BadLocationException; |
51 |
import javax.swing.text.JTextComponent; |
52 |
import javax.swing.text.View; |
53 |
import org.netbeans.api.editor.settings.FontColorNames; |
54 |
|
55 |
/** |
56 |
* Various draw layers are located here |
57 |
* |
58 |
* @author Miloslav Metelka |
59 |
* @version 1.00 |
60 |
* |
61 |
* @deprecated Please use Highlighting SPI instead, for details see |
62 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
63 |
*/ |
64 |
public class DrawLayerFactory { |
65 |
|
66 |
private static final Logger LOG = Logger.getLogger(DrawLayerFactory.class.getName()); |
67 |
|
68 |
/** Syntax draw layer name */ |
69 |
public static final String SYNTAX_LAYER_NAME = "syntax-layer"; // NOI18N |
70 |
|
71 |
/** Syntax draw layer visibility */ |
72 |
public static final int SYNTAX_LAYER_VISIBILITY = 1000; |
73 |
|
74 |
/** Annotation draw layer name */ |
75 |
public static final String ANNOTATION_LAYER_NAME = "annotation-layer"; // NOI18N |
76 |
|
77 |
/** Annotation draw layer visibility */ |
78 |
public static final int ANNOTATION_LAYER_VISIBILITY = 2100; |
79 |
|
80 |
/** Highlight search layer name */ |
81 |
public static final String HIGHLIGHT_SEARCH_LAYER_NAME = "highlight-search-layer"; // NOI18N |
82 |
|
83 |
/** Highlight search layer visibility */ |
84 |
public static final int HIGHLIGHT_SEARCH_LAYER_VISIBILITY = 9000; |
85 |
|
86 |
/** Incremental search layer name */ |
87 |
public static final String INC_SEARCH_LAYER_NAME = "inc-search-layer"; // NOI18N |
88 |
|
89 |
/** Incremental search layer visibility */ |
90 |
public static final int INC_SEARCH_LAYER_VISIBILITY = 9500; |
91 |
|
92 |
/** Search block layer name */ |
93 |
public static final String BLOCK_SEARCH_LAYER_NAME = "block-search-layer"; // NOI18N |
94 |
|
95 |
/** Search block layer visibility */ |
96 |
public static final int BLOCK_SEARCH_LAYER_VISIBILITY = 8500; |
97 |
|
98 |
/** Selection draw layer name */ |
99 |
public static final String CARET_LAYER_NAME = "caret-layer"; // NOI18N |
100 |
|
101 |
/** Selection draw layer visibility */ |
102 |
public static final int CARET_LAYER_VISIBILITY = 10000; |
103 |
|
104 |
|
105 |
/** Guarded layer name */ |
106 |
public static final String GUARDED_LAYER_NAME = "guarded-layer"; // NOI18N |
107 |
|
108 |
/** Guarded layer visibility */ |
109 |
public static final int GUARDED_LAYER_VISIBILITY = 1400; |
110 |
|
111 |
|
112 |
/** |
113 |
* Layer that colors the text according to the tokens that were parsed. |
114 |
* It's active all the time. |
115 |
* |
116 |
* @deprecated Please use Highlighting SPI instead, for details see |
117 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
118 |
*/ |
119 |
public static class SyntaxLayer extends DrawLayer.AbstractLayer { |
120 |
|
121 |
public SyntaxLayer() { |
122 |
super(SYNTAX_LAYER_NAME); |
123 |
} |
124 |
|
125 |
public void init(DrawContext ctx) { |
126 |
} |
127 |
|
128 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
129 |
return true; |
130 |
} |
131 |
|
132 |
public void updateContext(DrawContext ctx) { |
133 |
// Get the token type and docColorings |
134 |
TokenID tokenID = ctx.getTokenID(); |
135 |
TokenContextPath tcp = ctx.getTokenContextPath(); |
136 |
if (tokenID != null && tcp != null) { |
137 |
// Get the coloring according the name of the token |
138 |
String fullName = tcp.getFullTokenName(tokenID); |
139 |
Coloring c = ctx.getEditorUI().getColoring(fullName); |
140 |
if (c != null) { |
141 |
c.apply(ctx); |
142 |
|
143 |
} else { // Token coloring null, try category |
144 |
TokenCategory cat = tokenID.getCategory(); |
145 |
if (cat != null) { |
146 |
fullName = tcp.getFullTokenName(cat); |
147 |
c = ctx.getEditorUI().getColoring(fullName); |
148 |
if (c != null) { |
149 |
c.apply(ctx); |
150 |
} |
151 |
} |
152 |
} |
153 |
} |
154 |
} |
155 |
|
156 |
} |
157 |
|
158 |
|
159 |
/** |
160 |
* This layer colors the line by a color specified in constructor |
161 |
* It requires only activation mark since it deactivates automatically |
162 |
* at the end of line. |
163 |
* |
164 |
* @deprecated Please use Highlighting SPI instead, for details see |
165 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
166 |
*/ |
167 |
public static abstract class ColorLineLayer extends DrawLayer.AbstractLayer { |
168 |
|
169 |
/** Coloring to use for highlighting */ |
170 |
Coloring coloring; |
171 |
|
172 |
public ColorLineLayer(String name) { |
173 |
super(name); |
174 |
} |
175 |
|
176 |
public boolean extendsEOL() { |
177 |
return true; |
178 |
} |
179 |
|
180 |
public void init(DrawContext ctx) { |
181 |
coloring = null; |
182 |
} |
183 |
|
184 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
185 |
boolean active; |
186 |
if (mark == null) { |
187 |
View view = ctx instanceof DrawEngine.DrawInfo ? ((DrawEngine.DrawInfo)ctx).view.getParent() : null; |
188 |
if (view instanceof DrawEngineLineView) { |
189 |
DrawEngineLineView delv = (DrawEngineLineView)view; |
190 |
mark = getFoldedMark(delv, getName()); |
191 |
if (mark == null) { |
192 |
view = delv.getView(delv.getViewCount() -1); |
193 |
if (view instanceof DrawEngineLineView) { |
194 |
delv = (DrawEngineLineView) view; |
195 |
mark = getFoldedMark(delv, getName()); |
196 |
} |
197 |
} |
198 |
} |
199 |
} |
200 |
if (mark != null) { |
201 |
active = (ctx.getEditorUI().getComponent() != null) |
202 |
&& mark.activateLayer; |
203 |
if (active) { |
204 |
try { |
205 |
BaseDocument doc = ctx.getEditorUI().getDocument(); |
206 |
int nextRowStartPos = Utilities.getRowStart( |
207 |
doc, ctx.getFragmentOffset(), 1); |
208 |
if (nextRowStartPos < 0) { // end of doc |
209 |
nextRowStartPos = Integer.MAX_VALUE; |
210 |
} |
211 |
setNextActivityChangeOffset(nextRowStartPos); |
212 |
|
213 |
} catch (BadLocationException e) { |
214 |
active = false; |
215 |
} |
216 |
} |
217 |
} else { |
218 |
active = false; |
219 |
} |
220 |
return active; |
221 |
} |
222 |
|
223 |
public void updateContext(DrawContext ctx) { |
224 |
if (coloring == null) { |
225 |
coloring = getColoring(ctx); |
226 |
} |
227 |
if (coloring != null) { |
228 |
coloring.apply(ctx); |
229 |
} |
230 |
} |
231 |
|
232 |
protected abstract Coloring getColoring(DrawContext ctx); |
233 |
|
234 |
} |
235 |
|
236 |
|
237 |
/** Layer that covers selection services provided by caret. |
238 |
* This layer assumes that both caretMark and selectionMark in |
239 |
* BaseCaret are properly served so that their active flags |
240 |
* are properly set. |
241 |
* |
242 |
* @deprecated Please use Highlighting SPI instead, for details see |
243 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
244 |
*/ |
245 |
public static class CaretLayer extends DrawLayer.AbstractLayer { |
246 |
|
247 |
Coloring coloring; |
248 |
|
249 |
public CaretLayer() { |
250 |
super(CARET_LAYER_NAME); |
251 |
} |
252 |
|
253 |
public boolean extendsEmptyLine() { |
254 |
return true; |
255 |
} |
256 |
|
257 |
public void init(DrawContext ctx) { |
258 |
coloring = null; |
259 |
} |
260 |
|
261 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
262 |
boolean active; |
263 |
if (mark != null) { |
264 |
active = mark.activateLayer; |
265 |
} else { |
266 |
JTextComponent c = ctx.getEditorUI().getComponent(); |
267 |
active = (c != null) && Utilities.isSelectionShowing(c) |
268 |
&& ctx.getFragmentOffset() >= c.getSelectionStart() |
269 |
&& ctx.getFragmentOffset() < c.getSelectionEnd(); |
270 |
} |
271 |
|
272 |
return active; |
273 |
} |
274 |
|
275 |
public void updateContext(DrawContext ctx) { |
276 |
if (coloring == null) { |
277 |
coloring = ctx.getEditorUI().getColoring(FontColorNames.SELECTION_COLORING); |
278 |
} |
279 |
if (coloring != null) { |
280 |
coloring.apply(ctx); |
281 |
} |
282 |
} |
283 |
|
284 |
} |
285 |
|
286 |
|
287 |
/** Highlight search layer highlights all occurences |
288 |
* of the searched string in text. |
289 |
* |
290 |
* @deprecated Please use Highlighting SPI instead, for details see |
291 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
292 |
*/ |
293 |
public static class HighlightSearchLayer extends DrawLayer.AbstractLayer { |
294 |
|
295 |
/** Pairs of start and end position of the found string */ |
296 |
int blocks[] = new int[] { -1, -1 }; |
297 |
|
298 |
/** Coloring to use for highlighting */ |
299 |
Coloring coloring; |
300 |
|
301 |
/** Current index for painting */ |
302 |
int curInd; |
303 |
|
304 |
/** Enabled flag */ |
305 |
boolean enabled; |
306 |
|
307 |
public HighlightSearchLayer() { |
308 |
super(HIGHLIGHT_SEARCH_LAYER_NAME); |
309 |
} |
310 |
|
311 |
public boolean isEnabled() { |
312 |
return enabled; |
313 |
} |
314 |
|
315 |
public void setEnabled(boolean enabled) { |
316 |
this.enabled = enabled; |
317 |
} |
318 |
|
319 |
public void init(DrawContext ctx) { |
320 |
if (enabled) { |
321 |
try { |
322 |
BaseDocument doc = ctx.getEditorUI().getDocument(); |
323 |
blocks = FindSupport.getFindSupport().getBlocks(blocks, |
324 |
doc, ctx.getStartOffset(), ctx.getEndOffset()); |
325 |
} catch (BadLocationException e) { |
326 |
blocks = new int[] { -1, -1 }; |
327 |
} |
328 |
coloring = null; // reset so it will be re-read |
329 |
curInd = 0; |
330 |
} |
331 |
} |
332 |
|
333 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
334 |
boolean active; |
335 |
if (enabled) { |
336 |
int pos = ctx.getFragmentOffset(); |
337 |
if (pos == blocks[curInd]) { |
338 |
active = true; |
339 |
setNextActivityChangeOffset(blocks[curInd + 1]); |
340 |
|
341 |
} else if (pos == blocks[curInd + 1]) { |
342 |
active = false; |
343 |
curInd += 2; |
344 |
setNextActivityChangeOffset(blocks[curInd]); |
345 |
if (pos == blocks[curInd]) { // just follows |
346 |
setNextActivityChangeOffset(blocks[curInd + 1]); |
347 |
active = true; |
348 |
} |
349 |
|
350 |
} else { |
351 |
setNextActivityChangeOffset(blocks[curInd]); |
352 |
active = false; |
353 |
} |
354 |
} else { |
355 |
active = false; |
356 |
} |
357 |
|
358 |
return active; |
359 |
} |
360 |
|
361 |
public void updateContext(DrawContext ctx) { |
362 |
int pos = ctx.getFragmentOffset(); |
363 |
if (pos >= blocks[curInd] && pos < blocks[curInd + 1]) { |
364 |
if (coloring == null) { |
365 |
coloring = ctx.getEditorUI().getColoring(FontColorNames.HIGHLIGHT_SEARCH_COLORING); |
366 |
} |
367 |
if (coloring != null) { |
368 |
coloring.apply(ctx); |
369 |
} |
370 |
} |
371 |
} |
372 |
|
373 |
} |
374 |
|
375 |
/** Layer covering incremental search. There are just two positions |
376 |
* begining and end of the searched string |
377 |
* |
378 |
* @deprecated Please use Highlighting SPI instead, for details see |
379 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
380 |
*/ |
381 |
public static class IncSearchLayer extends DrawLayer.AbstractLayer { |
382 |
|
383 |
/** Position where the searched string begins */ |
384 |
int pos; |
385 |
|
386 |
/** Length of area to highlight */ |
387 |
int len; |
388 |
|
389 |
/** Whether this layer is enabled */ |
390 |
boolean enabled; |
391 |
|
392 |
boolean invert; |
393 |
|
394 |
public IncSearchLayer() { |
395 |
super(INC_SEARCH_LAYER_NAME); |
396 |
} |
397 |
|
398 |
public boolean isEnabled() { |
399 |
return enabled; |
400 |
} |
401 |
|
402 |
public void setEnabled(boolean enabled) { |
403 |
this.enabled = enabled; |
404 |
} |
405 |
|
406 |
void setArea(int pos, int len) { |
407 |
this.pos = pos; |
408 |
this.len = len; |
409 |
} |
410 |
|
411 |
public int getOffset() { |
412 |
return pos; |
413 |
} |
414 |
|
415 |
public int getLength() { |
416 |
return len; |
417 |
} |
418 |
|
419 |
public void init(DrawContext ctx) { |
420 |
setNextActivityChangeOffset(enabled ? pos : Integer.MAX_VALUE); |
421 |
} |
422 |
|
423 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
424 |
boolean active = false; |
425 |
if (enabled) { |
426 |
if (ctx.getFragmentOffset() == pos) { |
427 |
active = true; |
428 |
setNextActivityChangeOffset(pos + len); |
429 |
} |
430 |
} |
431 |
|
432 |
return active; |
433 |
} |
434 |
|
435 |
/** current INC_SEARCH_COLORING is used only in block search. |
436 |
* if there is no search, use selection |
437 |
* @param invert if true - selection coloring is used |
438 |
*/ |
439 |
void setInversion(boolean invert){ |
440 |
this.invert = invert; |
441 |
} |
442 |
|
443 |
public void updateContext(DrawContext ctx) { |
444 |
if (!invert) { |
445 |
Coloring coloring = ctx.getEditorUI().getColoring(FontColorNames.INC_SEARCH_COLORING); |
446 |
if (coloring != null) { |
447 |
coloring.apply(ctx); |
448 |
} |
449 |
} else { |
450 |
Coloring invertedColoring = ctx.getEditorUI().getColoring(FontColorNames.SELECTION_COLORING); |
451 |
if (invertedColoring != null) { |
452 |
invertedColoring.apply(ctx); |
453 |
} |
454 |
} |
455 |
} |
456 |
} // End of IncSearchLayer class |
457 |
|
458 |
/** |
459 |
* @deprecated Please use Highlighting SPI instead, for details see |
460 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
461 |
*/ |
462 |
public static class BlockSearchLayer extends DrawLayer.AbstractLayer { |
463 |
|
464 |
/** Position where the searched string begins */ |
465 |
int pos; |
466 |
|
467 |
/** Length of area to highlight */ |
468 |
int len; |
469 |
|
470 |
/** Whether this layer is enabled */ |
471 |
boolean enabled; |
472 |
|
473 |
public BlockSearchLayer() { |
474 |
super(BLOCK_SEARCH_LAYER_NAME); |
475 |
} |
476 |
|
477 |
public boolean extendsEmptyLine(){ |
478 |
return true; |
479 |
} |
480 |
|
481 |
public boolean isEnabled() { |
482 |
return enabled; |
483 |
} |
484 |
|
485 |
public void setEnabled(boolean enabled) { |
486 |
this.enabled = enabled; |
487 |
} |
488 |
|
489 |
void setArea(int pos, int len) { |
490 |
this.pos = pos; |
491 |
this.len = len; |
492 |
} |
493 |
|
494 |
int getOffset() { |
495 |
return pos; |
496 |
} |
497 |
|
498 |
int getLength() { |
499 |
return len; |
500 |
} |
501 |
|
502 |
public void init(DrawContext ctx) { |
503 |
setNextActivityChangeOffset(enabled ? pos : Integer.MAX_VALUE); |
504 |
} |
505 |
|
506 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
507 |
boolean active = false; |
508 |
if (enabled) { |
509 |
int fragOffset = ctx.getFragmentOffset(); |
510 |
if (fragOffset >= pos && fragOffset<(pos+len)) { |
511 |
active = true; |
512 |
try { |
513 |
BaseDocument doc = ctx.getEditorUI().getDocument(); |
514 |
int nextRowStartPos = Utilities.getRowStart( |
515 |
doc, fragOffset, 1); |
516 |
if (nextRowStartPos < 0) { // end of doc |
517 |
nextRowStartPos = Integer.MAX_VALUE; |
518 |
} |
519 |
setNextActivityChangeOffset(Math.min(nextRowStartPos,(pos+len))); |
520 |
|
521 |
} catch (BadLocationException e) { |
522 |
active = false; |
523 |
} |
524 |
|
525 |
} |
526 |
} |
527 |
|
528 |
return active; |
529 |
} |
530 |
|
531 |
public void updateContext(DrawContext ctx) { |
532 |
Coloring coloring = ctx.getEditorUI().getColoring(FontColorNames.BLOCK_SEARCH_COLORING); |
533 |
if (coloring != null) { |
534 |
coloring.apply(ctx); |
535 |
} |
536 |
} |
537 |
} // End of BlockSearchLayer class |
538 |
|
539 |
// |
540 |
// XXX: Deprecated and not used anymore. Can be removed. |
541 |
// |
542 |
// /** Layer for guarded blocks |
543 |
// * |
544 |
// * @deprecated Please use Highlighting SPI instead, for details see |
545 |
// * <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
546 |
// */ |
547 |
// static class GuardedLayer extends ColorLineLayer { |
548 |
// |
549 |
// GuardedDocument doc; |
550 |
// |
551 |
// GuardedLayer() { |
552 |
// super(GUARDED_LAYER_NAME); |
553 |
// } |
554 |
// |
555 |
// public void init(DrawContext ctx) { |
556 |
// super.init(ctx); |
557 |
// doc = (GuardedDocument)ctx.getEditorUI().getDocument(); |
558 |
// } |
559 |
// |
560 |
// public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
561 |
// boolean active; |
562 |
// if (mark != null) { |
563 |
// active = mark.activateLayer; |
564 |
// } else { |
565 |
// active = doc.isPosGuarded(ctx.getFragmentOffset()); |
566 |
// } |
567 |
// |
568 |
// return active; |
569 |
// } |
570 |
// |
571 |
// protected Coloring getColoring(DrawContext ctx) { |
572 |
// return ctx.getEditorUI().getColoring(SettingsNames.GUARDED_COLORING); |
573 |
// } |
574 |
// |
575 |
// } |
576 |
|
577 |
|
578 |
|
579 |
/** |
580 |
* Style layer getting color settings from particular style |
581 |
* |
582 |
* @deprecated Please use Highlighting SPI instead, for details see |
583 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
584 |
*/ |
585 |
public static class StyleLayer extends DrawLayer.AbstractLayer { |
586 |
|
587 |
protected Style style; |
588 |
|
589 |
protected MarkChain markChain; |
590 |
|
591 |
protected Color backColor; |
592 |
|
593 |
protected Color foreColor; |
594 |
|
595 |
public StyleLayer(String layerName, BaseDocument doc, Style style) { |
596 |
super(layerName); |
597 |
this.style = style; |
598 |
markChain = new MarkChain(doc, layerName); |
599 |
} |
600 |
|
601 |
public boolean extendsEOL() { |
602 |
return true; |
603 |
} |
604 |
|
605 |
public final MarkChain getMarkChain() { |
606 |
return markChain; |
607 |
} |
608 |
|
609 |
public void init(DrawContext ctx) { |
610 |
foreColor = StyleConstants.getForeground(style); |
611 |
backColor = StyleConstants.getBackground(style); |
612 |
} |
613 |
|
614 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
615 |
boolean active = false; |
616 |
if (mark != null) { |
617 |
active = (ctx.getEditorUI().getComponent() != null) |
618 |
&& mark.activateLayer; |
619 |
if (active) { |
620 |
try { |
621 |
BaseDocument doc = ctx.getEditorUI().getDocument(); |
622 |
int nextRowStartPos = Utilities.getRowStart( |
623 |
doc, ctx.getFragmentOffset(), 1); |
624 |
if (nextRowStartPos < 0) { // end of doc |
625 |
nextRowStartPos = Integer.MAX_VALUE; |
626 |
} |
627 |
|
628 |
setNextActivityChangeOffset(nextRowStartPos); |
629 |
|
630 |
} catch (BadLocationException e) { |
631 |
active = false; |
632 |
} |
633 |
} |
634 |
|
635 |
} |
636 |
|
637 |
return active; |
638 |
} |
639 |
|
640 |
public void updateContext(DrawContext ctx) { |
641 |
if (foreColor != null) { |
642 |
ctx.setForeColor(foreColor); |
643 |
} |
644 |
if (backColor != null) { |
645 |
ctx.setBackColor(backColor); |
646 |
} |
647 |
} |
648 |
|
649 |
public String toString() { |
650 |
return super.toString() + ((markChain != null) ? (", " + markChain) : ""); // NOI18N |
651 |
} |
652 |
|
653 |
} |
654 |
|
655 |
/** |
656 |
* Test layer for coloring the specific words |
657 |
* |
658 |
* @deprecated Please use Highlighting SPI instead, for details see |
659 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
660 |
*/ |
661 |
public static class WordColoringLayer extends DrawLayer.AbstractLayer { |
662 |
|
663 |
protected StringMap stringMap = new StringMap(); |
664 |
|
665 |
public WordColoringLayer(String name) { |
666 |
super(name); |
667 |
} |
668 |
|
669 |
public void put(String s, Coloring c) { |
670 |
stringMap.put(s, c); |
671 |
} |
672 |
|
673 |
public void put(String[] strings, Coloring c) { |
674 |
for (int i = 0; i < strings.length; i++) { |
675 |
put(strings[i], c); |
676 |
} |
677 |
} |
678 |
|
679 |
public void put(List stringList, Coloring c) { |
680 |
String strings[] = new String[stringList.size()]; |
681 |
stringList.toArray(strings); |
682 |
put(strings, c); |
683 |
} |
684 |
|
685 |
public void init(DrawContext ctx) { |
686 |
} |
687 |
|
688 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
689 |
return true; |
690 |
} |
691 |
|
692 |
public void updateContext(DrawContext ctx) { |
693 |
Coloring c = (Coloring)stringMap.get(ctx.getBuffer(), |
694 |
ctx.getTokenOffset(), ctx.getTokenLength()); |
695 |
if (c != null) { |
696 |
c.apply(ctx); |
697 |
} |
698 |
} |
699 |
|
700 |
} |
701 |
|
702 |
/** |
703 |
* Annotation layer for drawing of annotations. Each mark which is stored in markChain has |
704 |
* corresponding Annotation. More than one Annotation can share one mark. In this case |
705 |
* the only one annotation is active and this must be drawn. |
706 |
* |
707 |
* @deprecated Please use Highlighting SPI instead, for details see |
708 |
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>. |
709 |
*/ |
710 |
public static class AnnotationLayer extends DrawLayer.AbstractLayer { |
711 |
|
712 |
/** Current coloring */ |
713 |
private Coloring coloring; |
714 |
|
715 |
/** Chain of marks attached to this layer */ |
716 |
private MarkChain markChain; |
717 |
|
718 |
public AnnotationLayer(BaseDocument doc) { |
719 |
super(ANNOTATION_LAYER_NAME); |
720 |
coloring = null; |
721 |
markChain = new MarkChain(doc, ANNOTATION_LAYER_NAME); |
722 |
} |
723 |
|
724 |
/** Get chain of marks attached to this draw layer |
725 |
* @return mark chain */ |
726 |
public final MarkChain getMarkChain() { |
727 |
return markChain; |
728 |
} |
729 |
|
730 |
public boolean extendsEOL() { |
731 |
return true; |
732 |
} |
733 |
|
734 |
public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { |
735 |
int nextActivityOffset; |
736 |
coloring = null; |
737 |
// LOG.setLevel(Level.FINE); |
738 |
// if (LOG.isLoggable(Level.FINE)) { |
739 |
// LOG.fine(" ctx-offset=" + ctx.getFragmentOffset() + ", mark=" + mark + '\n'); |
740 |
// } |
741 |
|
742 |
if (mark == null) { |
743 |
View view = ctx instanceof DrawEngine.DrawInfo ? ((DrawEngine.DrawInfo)ctx).view : null; |
744 |
if (view instanceof DrawEngineLineView) { |
745 |
mark = getFoldedMark((DrawEngineLineView)view, getName()); |
746 |
} |
747 |
} |
748 |
|
749 |
if (mark == null) { |
750 |
return false; |
751 |
} |
752 |
|
753 |
if (ctx.getEditorUI().getComponent() == null || !mark.activateLayer) { |
754 |
return false; |
755 |
} |
756 |
|
757 |
BaseDocument doc = ctx.getEditorUI().getDocument(); |
758 |
|
759 |
// Gets the active annotation attached to this mark. It is possible that |
760 |
// no active annotation might exist for the mark, e.g. there can be |
761 |
// mark at the beginning of the line for a whole line annotation |
762 |
// and there can be mark in the middle of the line for a line-part annotation |
763 |
AnnotationDesc anno = doc.getAnnotations().getActiveAnnotation(mark); |
764 |
if (anno == null) { |
765 |
// if no active annotation was found for the given mark, check |
766 |
// whether we are not already drawing some other annotation. If that's |
767 |
// true we have to continue drawing it (means return true here) |
768 |
AnnotationDesc activeAnno = doc.getAnnotations().getLineActiveAnnotation(mark); |
769 |
if (activeAnno == null) { |
770 |
return false; |
771 |
} |
772 |
if (ctx.getFragmentOffset() >= activeAnno.getOffset()) { |
773 |
if (ctx.getFragmentOffset() < activeAnno.getOffset() + activeAnno.getLength() || activeAnno.isWholeLine()) { |
774 |
coloring = activeAnno.getColoring(); |
775 |
return true; |
776 |
} |
777 |
} |
778 |
return false; |
779 |
} |
780 |
|
781 |
// if (LOG.isLoggable(Level.FINE)) { |
782 |
// LOG.log(Level.FINE, "anno: o=" + anno.getOffset() + ", l=" + anno.getLength() + ", wl=" + anno.isWholeLine() |
783 |
// + ", m=" + mark + ", ctx-offset=" + ctx.getFragmentOffset() + '\n'); |
784 |
// } |
785 |
if (anno.isWholeLine()) { |
786 |
try { |
787 |
nextActivityOffset = Utilities.getRowEnd(doc, ctx.getFragmentOffset()); |
788 |
} catch (BadLocationException ble) { |
789 |
LOG.log(Level.FINE, null, ble); |
790 |
return false; |
791 |
} |
792 |
} else { |
793 |
if (ctx.getFragmentOffset() < anno.getOffset()) { // Queried below annotation start |
794 |
setNextActivityChangeOffset(anno.getOffset()); |
795 |
return false; |
796 |
} |
797 |
nextActivityOffset = anno.getOffset() + anno.getLength(); |
798 |
if (ctx.getFragmentOffset() >= nextActivityOffset) { // Queried above annotation end |
799 |
try { |
800 |
setNextActivityChangeOffset(Utilities.getRowEnd(doc, ctx.getFragmentOffset())); |
801 |
} catch (BadLocationException ble) { |
802 |
LOG.log(Level.FINE, null, ble); |
803 |
return false; |
804 |
} |
805 |
return false; |
806 |
} |
807 |
} |
808 |
|
809 |
setNextActivityChangeOffset(nextActivityOffset); |
810 |
coloring = anno.getColoring(); |
811 |
|
812 |
// The following code ensures that if active annotation does not |
813 |
// have highlight the color of next one will be used. |
814 |
// It was decided that it will not be used |
815 |
// |
816 |
// if (coloring.getBackColor() == null) { |
817 |
// AnnotationDesc[] annos = doc.getAnnotations().getPasiveAnnotations(anno.getLine()); |
818 |
// if (annos != null) { |
819 |
// for (int i=0; i<annos.length; i++) { |
820 |
// if (annos[i].getColoring().getBackColor() != null) { |
821 |
// coloring = annos[i].getColoring(); |
822 |
// break; |
823 |
// } |
824 |
// } |
825 |
// } |
826 |
// } |
827 |
|
828 |
return true; |
829 |
} |
830 |
|
831 |
public void updateContext(DrawContext ctx) { |
832 |
if (coloring != null) { |
833 |
coloring.apply(ctx); |
834 |
} |
835 |
} |
836 |
|
837 |
} |
838 |
|
839 |
private static MarkFactory.DrawMark getFoldedMark(DrawEngineLineView view, String layerName) { |
840 |
BaseDocument doc = (BaseDocument)view.getDocument(); |
841 |
int startPos = view.getStartOffset(); |
842 |
int endPos = view.getEndOffset() - 1; |
843 |
MarkVector docMarksStorage = doc.marksStorage; |
844 |
synchronized (docMarksStorage) { |
845 |
int low = 0; |
846 |
int high = docMarksStorage.getMarkCount() - 1; |
847 |
|
848 |
while (low < high) { // Unlike regular binary search only iterate (low < high) - code below handles that correctly |
849 |
int mid = (low + high) >> 1; |
850 |
int cmp = docMarksStorage.getMarkOffsetInternal(mid) - endPos; |
851 |
if (cmp < 0) |
852 |
low = mid + 1; |
853 |
else if (cmp > 0) |
854 |
high = mid - 1; |
855 |
else { // found |
856 |
while (++mid <= high && docMarksStorage.getMarkOffsetInternal(mid) == endPos) { } |
857 |
low = high = mid - 1; |
858 |
} |
859 |
} |
860 |
|
861 |
while (low >= 0 && low < docMarksStorage.getMarkCount()) { |
862 |
MultiMark mm = (MultiMark)docMarksStorage.getMark(low--); |
863 |
if (mm.isValid() && mm.getOffset() <= endPos) { |
864 |
if (mm.getOffset() < startPos) { |
865 |
break; |
866 |
} |
867 |
Mark mrk = doc.marks.get(mm); |
868 |
if (mrk instanceof MarkFactory.DrawMark && layerName.equals(((MarkFactory.DrawMark)mrk).layerName)) { |
869 |
return (MarkFactory.DrawMark)mrk; |
870 |
} |
871 |
} |
872 |
} |
873 |
} |
874 |
|
875 |
return null; |
876 |
} |
877 |
} |