2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.openapi
.editor
.impl
;
18 import com
.intellij
.openapi
.editor
.Document
;
19 import com
.intellij
.openapi
.editor
.event
.DocumentEvent
;
20 import com
.intellij
.openapi
.editor
.event
.DocumentListener
;
21 import com
.intellij
.openapi
.editor
.ex
.PrioritizedDocumentListener
;
22 import com
.intellij
.openapi
.editor
.markup
.RangeHighlighter
;
23 import com
.intellij
.util
.containers
.SortedList
;
25 import java
.util
.Comparator
;
26 import java
.util
.Iterator
;
27 import java
.util
.List
;
29 public abstract class HighlighterList
{
30 private final SortedList
<RangeHighlighterImpl
> mySegmentHighlighters
= new SortedList
<RangeHighlighterImpl
>(MY_RANGE_COMPARATOR
) {
32 protected void sort(List
<RangeHighlighterImpl
> delegate
) {
33 Iterator
<RangeHighlighterImpl
> it
= delegate
.iterator();
34 boolean needSort
= false;
35 RangeHighlighterImpl lastHighlighter
= null;
37 while (it
.hasNext()) {
38 RangeHighlighterImpl highlighter
= it
.next();
39 if (!highlighter
.isValid()) {
44 if (lastHighlighter
!= null) {
45 if (!needSort
) needSort
= MY_RANGE_COMPARATOR
.compare(lastHighlighter
, highlighter
) > 0;
48 lastHighlighter
= highlighter
;
57 public boolean remove(Object o
) {
58 if (o
instanceof RangeHighlighterImpl
) {
59 if (!((RangeHighlighterImpl
)o
).isValid()) return false;
61 return super.remove(o
);
65 private boolean myIsDirtied
= false;
66 private final DocumentListener myDocumentListener
;
67 private final Document myDoc
;
68 private int myLongestHighlighterLength
= 0;
70 private static final Comparator
<RangeHighlighterImpl
> MY_RANGE_COMPARATOR
= new Comparator
<RangeHighlighterImpl
>() {
71 public int compare(RangeHighlighterImpl r1
, RangeHighlighterImpl r2
) {
72 if (r1
.getAffectedAreaStartOffset() != r2
.getAffectedAreaStartOffset()) {
73 return r1
.getAffectedAreaStartOffset() - r2
.getAffectedAreaStartOffset();
76 if (r1
.getLayer() != r2
.getLayer()) {
77 return r2
.getLayer() - r1
.getLayer();
80 return (int) (r2
.getId() - r1
.getId());
84 public HighlighterList(Document doc
) {
85 myDocumentListener
= new PrioritizedDocumentListener() {
86 public int getPriority() {
87 return 0; // Need to make sure we invalidate all the stuff before someone (like LineStatusTracker) starts to modify highlights.
90 public void beforeDocumentChange(DocumentEvent event
) {}
92 public void documentChanged(DocumentEvent e
) {
94 mySegmentHighlighters
.markDirty();
98 myDoc
.addDocumentListener(myDocumentListener
);
101 public void dispose() {
102 myDoc
.removeDocumentListener(myDocumentListener
);
105 public int getLongestHighlighterLength() {
106 return myLongestHighlighterLength
;
109 private void sortMarkers() {
110 assertDispatchThread();
111 myLongestHighlighterLength
= 0;
113 Iterator
<RangeHighlighterImpl
> iterator
= mySegmentHighlighters
.iterator();
114 while (iterator
.hasNext()) {
115 RangeHighlighter rangeHighlighter
= iterator
.next();
116 if (rangeHighlighter
.isValid()) {
117 myLongestHighlighterLength
= Math
.max(myLongestHighlighterLength
, rangeHighlighter
.getEndOffset() - rangeHighlighter
.getStartOffset());
127 protected abstract void assertDispatchThread();
129 Iterator
<RangeHighlighterImpl
> getHighlighterIterator() {
130 if (myIsDirtied
) sortMarkers();
131 return mySegmentHighlighters
.iterator();
134 List
<RangeHighlighterImpl
> getSortedHighlighters() {
135 if (myIsDirtied
) sortMarkers();
136 return mySegmentHighlighters
;
139 void addSegmentHighlighter(RangeHighlighter segmentHighlighter
) {
140 assertDispatchThread();
142 mySegmentHighlighters
.add((RangeHighlighterImpl
)segmentHighlighter
);
145 void removeSegmentHighlighter(RangeHighlighter segmentHighlighter
) {
146 assertDispatchThread();
149 //noinspection SuspiciousMethodCalls
150 mySegmentHighlighters
.remove(segmentHighlighter
);