| /* |
| * Copyright 2000-2009 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.diff.impl.incrementalMerge; |
| |
| import com.intellij.openapi.diff.ex.DiffFragment; |
| import com.intellij.openapi.diff.impl.DiffUtil; |
| import com.intellij.openapi.diff.impl.util.TextDiffType; |
| import com.intellij.openapi.editor.colors.EditorColorsScheme; |
| import com.intellij.openapi.editor.markup.*; |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.util.ui.UIUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.awt.*; |
| |
| public class ChangeType { |
| |
| private static final int LAYER = HighlighterLayer.SELECTION - 1; |
| private static final ChangeType INSERT = new ChangeType(TextDiffType.INSERT, false); |
| private static final ChangeType DELETED = new ChangeType(TextDiffType.DELETED, false); |
| private static final ChangeType CHANGE = new ChangeType(TextDiffType.CHANGED, false); |
| static final ChangeType CONFLICT = new ChangeType(TextDiffType.CONFLICT, false); |
| |
| private final TextDiffType myDiffType; |
| private final boolean myApplied; |
| |
| private ChangeType(TextDiffType diffType, boolean applied) { |
| myApplied = applied; |
| if (applied) { |
| myDiffType = TextDiffType.deriveApplied(diffType); |
| } |
| else { |
| myDiffType = diffType; |
| } |
| } |
| |
| public boolean isApplied() { |
| return myApplied; |
| } |
| |
| @NotNull |
| public static ChangeType deriveApplied(ChangeType type) { |
| return new ChangeType(type.myDiffType, true); |
| } |
| |
| @Nullable |
| public RangeHighlighter addMarker(ChangeSide changeSide, ChangeHighlighterHolder markup) { |
| String text = changeSide.getText(); |
| if (text != null && text.length() > 0) { |
| return addBlock(text, changeSide, markup, myDiffType); |
| } |
| else { |
| return addLine(markup, changeSide.getStartLine(), myDiffType, SeparatorPlacement.TOP); |
| } |
| } |
| |
| @NotNull |
| public TextDiffType getTypeKey() { |
| return myDiffType; |
| } |
| |
| @NotNull |
| public TextDiffType getTextDiffType() { |
| return getTypeKey(); |
| } |
| |
| @Nullable |
| private RangeHighlighter addBlock(String text, ChangeSide changeSide, final ChangeHighlighterHolder markup, TextDiffType diffType) { |
| EditorColorsScheme colorScheme = markup.getEditor().getColorsScheme(); |
| Color separatorColor = getSeparatorColor(diffType.getLegendColor(colorScheme)); |
| |
| int length = text.length(); |
| int start = changeSide.getStart(); |
| int end = start + length; |
| RangeHighlighter highlighter = markup.addRangeHighlighter(start, end, LAYER, diffType, HighlighterTargetArea.EXACT_RANGE, myApplied); |
| |
| LineSeparatorRenderer lineSeparatorRenderer = new LineSeparatorRenderer() { |
| @Override |
| public void drawLine(Graphics g, int x1, int x2, int y) { |
| Graphics2D g2 = (Graphics2D)g; |
| Color color = myDiffType.getPolygonColor(markup.getEditor()); |
| if (color != null) { |
| if (myApplied) { |
| UIUtil.drawBoldDottedLine(g2, x1, x2, y, null, color, false); |
| } |
| else { |
| UIUtil.drawLine(g2, x1, y, x2, y, null, DiffUtil.getFramingColor(color)); |
| } |
| } |
| } |
| }; |
| |
| if (highlighter != null) { |
| highlighter.setLineSeparatorPlacement(SeparatorPlacement.TOP); |
| highlighter.setLineSeparatorColor(separatorColor); |
| highlighter.setLineSeparatorRenderer(lineSeparatorRenderer); |
| } |
| |
| if (text.charAt(length - 1) == '\n') { |
| end--; |
| } |
| |
| highlighter = markup.addRangeHighlighter(start, end, LAYER, TextDiffType.NONE, HighlighterTargetArea.EXACT_RANGE, myApplied); |
| if (highlighter != null) { |
| highlighter.setLineSeparatorPlacement(SeparatorPlacement.BOTTOM); |
| highlighter.setLineSeparatorColor(separatorColor); |
| highlighter.setLineSeparatorRenderer(lineSeparatorRenderer); |
| } |
| return highlighter; |
| } |
| |
| @Nullable |
| private RangeHighlighter addLine(final ChangeHighlighterHolder markup, int line, final TextDiffType type, SeparatorPlacement placement) { |
| RangeHighlighter highlighter = markup.addLineHighlighter(line, LAYER, type, myApplied); |
| if (highlighter == null) { |
| return null; |
| } |
| highlighter.setLineSeparatorPlacement(placement); |
| highlighter.setLineSeparatorRenderer(new LineSeparatorRenderer() { |
| @Override |
| public void drawLine(Graphics g, int x1, int x2, int y) { |
| Graphics2D g2 = (Graphics2D)g; |
| Color color = myDiffType.getPolygonColor(markup.getEditor()); |
| if (color != null) { |
| if (type.isApplied()) { |
| UIUtil.drawBoldDottedLine(g2, x1, x2, y, null, color, false); |
| } |
| else { |
| DiffUtil.drawDoubleShadowedLine(g2, x1, x2, y, color); |
| } |
| } |
| } |
| }); |
| return highlighter; |
| } |
| |
| @NotNull |
| static ChangeType fromDiffFragment(DiffFragment fragment) { |
| if (fragment.getText1() == null) return INSERT; |
| if (fragment.getText2() == null) return DELETED; |
| return CHANGE; |
| } |
| |
| @NotNull |
| static ChangeType fromRanges(@NotNull TextRange left, @NotNull TextRange right) { |
| if (left.getLength() == 0) return INSERT; |
| if (right.getLength() == 0) return DELETED; |
| return CHANGE; |
| } |
| |
| public String toString() { |
| return myDiffType.getDisplayName(); |
| } |
| |
| @NotNull |
| public Color getSeparatorColor(@Nullable Color highlightColor) { |
| if (myApplied) { |
| return highlightColor == null ? Color.DARK_GRAY : highlightColor.darker(); |
| } |
| return Color.GRAY; |
| } |
| } |