IDEA-51739
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / editor / impl / HighlighterList.java
blob548f983e306ed54079ad6048bd8a15d54017e7f1
1 /*
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) {
31 @Override
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()) {
40 needSort = true;
41 it.remove();
44 if (lastHighlighter != null) {
45 if (!needSort) needSort = MY_RANGE_COMPARATOR.compare(lastHighlighter, highlighter) > 0;
48 lastHighlighter = highlighter;
51 if (needSort) {
52 super.sort(delegate);
56 @Override
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) {
93 myIsDirtied = true;
94 mySegmentHighlighters.markDirty();
97 myDoc = doc;
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());
119 else {
120 iterator.remove();
124 myIsDirtied = false;
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();
141 myIsDirtied = true;
142 mySegmentHighlighters.add((RangeHighlighterImpl)segmentHighlighter);
145 void removeSegmentHighlighter(RangeHighlighter segmentHighlighter) {
146 assertDispatchThread();
147 myIsDirtied = true;
149 //noinspection SuspiciousMethodCalls
150 mySegmentHighlighters.remove(segmentHighlighter);