/* * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.openapi.editor.impl; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.impl.event.DocumentEventImpl; import com.intellij.openapi.editor.markup.HighlighterTargetArea; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.util.DocumentUtil; import com.intellij.util.diff.FilesTooBigForDiffException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Implementation of the markup element for the editor and document. * @author max */ class PersistentRangeHighlighterImpl extends RangeHighlighterImpl { private int myLine; // for PersistentRangeHighlighterImpl only static PersistentRangeHighlighterImpl create(@NotNull MarkupModel model, int offset, int layer, @NotNull HighlighterTargetArea target, @Nullable TextAttributes textAttributes, boolean normalizeStartOffset) { int line = model.getDocument().getLineNumber(offset); int startOffset = normalizeStartOffset ? model.getDocument().getLineStartOffset(line) : offset; return new PersistentRangeHighlighterImpl(model, startOffset, line, layer, target, textAttributes); } private PersistentRangeHighlighterImpl(@NotNull MarkupModel model, int startOffset, int line, int layer, @NotNull HighlighterTargetArea target, @Nullable TextAttributes textAttributes) { super(model, startOffset, model.getDocument().getLineEndOffset(line), layer, target, textAttributes, false, false); myLine = line; } @Override protected void changedUpdateImpl(@NotNull DocumentEvent e) { // todo Denis Zhdanov DocumentEventImpl event = (DocumentEventImpl)e; final boolean shouldTranslateViaDiff = isValid() && PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, getStartOffset(), getEndOffset()); boolean wasTranslatedViaDiff = shouldTranslateViaDiff; if (shouldTranslateViaDiff) { wasTranslatedViaDiff = translatedViaDiff(e, event); } if (!wasTranslatedViaDiff) { super.changedUpdateImpl(e); if (isValid()) { myLine = getDocument().getLineNumber(getStartOffset()); int endLine = getDocument().getLineNumber(getEndOffset()); if (endLine != myLine) { setIntervalEnd(getDocument().getLineEndOffset(myLine)); } } } if (isValid() && getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) { setIntervalStart(DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), myLine)); setIntervalEnd(getDocument().getLineEndOffset(myLine)); } } private boolean translatedViaDiff(DocumentEvent e, DocumentEventImpl event) { try { myLine = event.translateLineViaDiff(myLine); } catch (FilesTooBigForDiffException ignored) { return false; } if (myLine < 0 || myLine >= getDocument().getLineCount()) { invalidate(e); } else { DocumentEx document = getDocument(); setIntervalStart(document.getLineStartOffset(myLine)); setIntervalEnd(document.getLineEndOffset(myLine)); } return true; } @Override public String toString() { return "PersistentRangeHighlighter" + (isGreedyToLeft() ? "[" : "(") + (isValid() ? "valid" : "invalid") + "," + getStartOffset() + "," + getEndOffset() + " - " + myLine + (isGreedyToRight() ? "]" : ")"); } }