blob: 01a13822a6b9ae694132834daa73c87e8b855bc4 [file] [log] [blame]
/*
* Copyright 2000-2014 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.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.fixtures.EditorMouseFixture;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase {
private Color DEFAULT_BACKGROUND;
private Color CARET_ROW_BACKGROUND;
private Color SELECTION_BACKGROUND;
@Override
public void setUp() throws Exception {
super.setUp();
EditorColorsScheme colorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
DEFAULT_BACKGROUND = colorsScheme.getDefaultBackground();
CARET_ROW_BACKGROUND = colorsScheme.getColor(EditorColors.CARET_ROW_COLOR);
SELECTION_BACKGROUND = colorsScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR);
assertEquals(3, new HashSet<Color>(Arrays.asList(DEFAULT_BACKGROUND, CARET_ROW_BACKGROUND, SELECTION_BACKGROUND)).size());
}
public void testBlockSelection() {
init("aa,<block>bb\n" +
"cc,d</block>d");
verifySplitting(true,
new Segment(0, 3, Color.BLACK),
new Segment(3, 4, Color.WHITE),
new Segment(4, 5, Color.BLACK),
new Segment(5, 6, Color.BLACK),
new Segment(6, 9, Color.BLACK),
new Segment(9, 10, Color.WHITE),
new Segment(10, 11, Color.BLACK));
}
public void testColumnModeBlockSelection() {
init("a\n" +
"bbb\n" +
"ccccc");
setColumnModeOn();
mouse().clickAt(0, 2).dragTo(2, 4).release();
verifySplitting(false,
new Segment(0, 1, DEFAULT_BACKGROUND),
new Segment(1, 2, DEFAULT_BACKGROUND).plus(1, DEFAULT_BACKGROUND).plus(2, SELECTION_BACKGROUND),
new Segment(2, 4, DEFAULT_BACKGROUND),
new Segment(4, 5, SELECTION_BACKGROUND),
new Segment(5, 6, DEFAULT_BACKGROUND).plus(1, SELECTION_BACKGROUND),
new Segment(6, 8, CARET_ROW_BACKGROUND),
new Segment(8, 10, SELECTION_BACKGROUND),
new Segment(10, 11, CARET_ROW_BACKGROUND));
}
public void testColumnModeBlockSelectionAtLastNonEmptyLine() {
init("a\n" +
"bbb\n" +
"ccccc");
setColumnModeOn();
mouse().clickAt(0, 2).dragTo(2, 6).release();
verifySplitting(false,
new Segment(0, 1, DEFAULT_BACKGROUND),
new Segment(1, 2, DEFAULT_BACKGROUND).plus(1, DEFAULT_BACKGROUND).plus(4, SELECTION_BACKGROUND),
new Segment(2, 4, DEFAULT_BACKGROUND),
new Segment(4, 5, SELECTION_BACKGROUND),
new Segment(5, 6, DEFAULT_BACKGROUND).plus(3, SELECTION_BACKGROUND),
new Segment(6, 8, CARET_ROW_BACKGROUND),
new Segment(8, 11, SELECTION_BACKGROUND),
new Segment(11, 11, null).plus(1, SELECTION_BACKGROUND));
}
public void testColumnModeBlockSelectionAtLastEmptyLine() {
init("a\n" +
"");
setColumnModeOn();
mouse().clickAt(1, 1).dragTo(1, 2).release();
verifySplitting(false,
new Segment(0, 1, DEFAULT_BACKGROUND),
new Segment(1, 2, DEFAULT_BACKGROUND),
new Segment(2, 2, null).plus(1, CARET_ROW_BACKGROUND).plus(1, SELECTION_BACKGROUND));
}
public void testColumnModeBlockSelectionAtEmptyLines() {
init("\n");
setColumnModeOn();
mouse().clickAt(0, 1).dragTo(1, 2).release();
verifySplitting(false,
new Segment(0, 1, DEFAULT_BACKGROUND).plus(1, DEFAULT_BACKGROUND).plus(1, SELECTION_BACKGROUND),
new Segment(1, 1, null).plus(1, CARET_ROW_BACKGROUND).plus(1, SELECTION_BACKGROUND));
}
public void testColumnModeSelectionWithCurrentBreakpointHighlighting() {
init("line1\n" +
"line2");
setColumnModeOn();
Color breakpointColor = Color.RED;
myFixture.getEditor().getMarkupModel().addLineHighlighter(0,
HighlighterLayer.SYNTAX + 1,
new TextAttributes(null, breakpointColor, null, null, 0));
Color currentDebuggingLineColor = Color.CYAN;
myFixture.getEditor().getMarkupModel().addLineHighlighter(0,
HighlighterLayer.SELECTION - 1,
new TextAttributes(null, currentDebuggingLineColor, null, null, 0));
mouse().clickAt(0, 4).dragTo(0, 6).release();
verifySplitting(false,
new Segment(0, 4, currentDebuggingLineColor),
new Segment(4, 5, SELECTION_BACKGROUND),
new Segment(5, 6, currentDebuggingLineColor).plus(1, SELECTION_BACKGROUND),
new Segment(6, 11, DEFAULT_BACKGROUND));
}
public void testLinesInRange() {
init(" line1\n" +
" line2");
Color breakpointColor = Color.RED;
myFixture.getEditor().getMarkupModel().addLineHighlighter(0,
HighlighterLayer.SYNTAX + 1,
new TextAttributes(null, breakpointColor, null, null, 0));
verifySplitting(false,
new Segment(0, 5, breakpointColor),
new Segment(5, 10, breakpointColor),
new Segment(10, 11, breakpointColor),
new Segment(11, 16, DEFAULT_BACKGROUND),
new Segment(16, 21, DEFAULT_BACKGROUND));
}
private void verifySplitting(boolean checkForegroundColor, @NotNull Segment... expectedSegments) {
EditorEx editor = (EditorEx)myFixture.getEditor();
IterationState iterationState = new IterationState(editor, 0, editor.getDocument().getTextLength(), true);
List<Segment> actualSegments = new ArrayList<Segment>();
do {
Segment segment = new Segment(iterationState.getStartOffset(),
iterationState.getEndOffset(),
checkForegroundColor ? iterationState.getMergedAttributes().getForegroundColor()
: iterationState.getMergedAttributes().getBackgroundColor());
readPastLineState(iterationState, segment);
actualSegments.add(segment);
iterationState.advance();
}
while (!iterationState.atEnd());
if (iterationState.hasPastFileEndBackgroundSegments()) {
Segment segment = new Segment(iterationState.getEndOffset(), iterationState.getEndOffset(), null);
readPastLineState(iterationState, segment);
actualSegments.add(segment);
}
Assert.assertArrayEquals(expectedSegments, actualSegments.toArray());
}
private static void readPastLineState(IterationState iterationState, Segment segment) {
while(iterationState.hasPastLineEndBackgroundSegment()) {
segment.plus(iterationState.getPastLineEndBackgroundSegmentWidth(), iterationState.getPastLineEndBackgroundAttributes().getBackgroundColor());
iterationState.advanceToNextPastLineEndBackgroundSegment();
}
}
private void init(String text) {
myFixture.configureByText(PlainTextFileType.INSTANCE, text);
EditorTestUtil.setEditorVisibleSize(myFixture.getEditor(), 1000, 1000);
}
private void setColumnModeOn() {
((EditorEx)myFixture.getEditor()).setColumnMode(true);
}
private EditorMouseFixture mouse() {
return new EditorMouseFixture((EditorImpl)myFixture.getEditor());
}
private static class Segment {
private final int start;
private final int end;
private final Color color;
private final List<Integer> pastLineEndSegmentWidths = new ArrayList<Integer>();
private final List<Color> pastLineEndSegmentColors = new ArrayList<Color>();
private Segment(int start, int end, Color color) {
this.start = start;
this.end = end;
this.color = color;
}
/**
* Adds a past-line-end background segment
*/
private Segment plus(int width, Color color) {
pastLineEndSegmentWidths.add(width);
pastLineEndSegmentColors.add(color);
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Segment segment = (Segment)o;
if (end != segment.end) return false;
if (start != segment.start) return false;
if (color != null ? !color.equals(segment.color) : segment.color != null) return false;
if (!pastLineEndSegmentColors.equals(segment.pastLineEndSegmentColors)) return false;
if (!pastLineEndSegmentWidths.equals(segment.pastLineEndSegmentWidths)) return false;
return true;
}
@Override
public int hashCode() {
int result = start;
result = 31 * result + end;
result = 31 * result + (color != null ? color.hashCode() : 0);
result = 31 * result + pastLineEndSegmentWidths.hashCode();
result = 31 * result + pastLineEndSegmentColors.hashCode();
return result;
}
@Override
public String toString() {
return "Segment{" +
"start=" + start +
", end=" + end +
", color=" + color +
(pastLineEndSegmentWidths.isEmpty() ? "" : ", pastLineEndSegmentWidths=" + pastLineEndSegmentWidths) +
(pastLineEndSegmentColors.isEmpty() ? "" : ", pastLineEndSegmentColors=" + pastLineEndSegmentColors) +
'}';
}
}
}