diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java index 8a7e01e03f57..51a366ff32f9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java @@ -20,10 +20,8 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.EditorGutterComponentEx; import com.intellij.openapi.editor.markup.LineMarkerRenderer; -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.*; @@ -34,27 +32,14 @@ import java.awt.*; public class DiffLineMarkerRenderer implements LineMarkerRenderer { @NotNull private final TextDiffType myDiffType; - @Nullable private final TextRange myTextRange; @NotNull - public static DiffLineMarkerRenderer createStandardInstance(@NotNull TextDiffType diffType) { - return new DiffLineMarkerRenderer(diffType, null); + public static DiffLineMarkerRenderer createInstance(@NotNull TextDiffType diffType) { + return new DiffLineMarkerRenderer(diffType); } - /** - * Creates an instance of the renderer that calculates the visual height of the text range and ensures that the drawn rectangle is at - * least as high as needed. - * @param diffType the type of the difference. - * @param range the highlighted text range. - */ - @NotNull - public static DiffLineMarkerRenderer createHeightAdjustingInstance(@NotNull TextDiffType diffType, @NotNull TextRange range) { - return new DiffLineMarkerRenderer(diffType, range); - } - - private DiffLineMarkerRenderer(@NotNull TextDiffType diffType, @Nullable TextRange range) { + private DiffLineMarkerRenderer(@NotNull TextDiffType diffType) { myDiffType = diffType; - myTextRange = range; } @Override @@ -71,10 +56,6 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer { int width = gutter.getWidth(); int height = range.height; - if (myTextRange != null) { - height = calcHeightInVisualLines(editor, myTextRange) * editor.getLineHeight(); - } - if (!myDiffType.isApplied()) { if (height > 2) { g.setColor(color); @@ -91,17 +72,4 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer { } } - private static int calcHeightInVisualLines(@NotNull Editor editor, @NotNull TextRange range) { - int startY = editor.offsetToVisualPosition(range.getStartOffset()).getLine(); - int endY = editor.offsetToVisualPosition(range.getEndOffset()).getLine(); - if (startY > endY) { - return 0; - } - return endY - startY + 1; - } - - @NotNull - public TextDiffType getType() { - return myDiffType; - } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java index 7e6201b6f50e..3d5b8d4dbcc1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java @@ -22,7 +22,9 @@ import com.intellij.openapi.diff.DiffViewer; import com.intellij.openapi.diff.LineTokenizer; import com.intellij.openapi.diff.ex.DiffFragment; import com.intellij.openapi.diff.impl.external.DiffManagerImpl; +import com.intellij.openapi.diff.impl.fragments.LineFragment; import com.intellij.openapi.diff.impl.util.FocusDiffSide; +import com.intellij.openapi.diff.impl.util.TextDiffType; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; @@ -111,4 +113,12 @@ public class DiffUtil { return backgroundColor.darker(); } + @NotNull + public static TextDiffType makeTextDiffType(@NotNull LineFragment fragment) { + TextDiffType type = TextDiffType.create(fragment.getType()); + if (fragment.getChildrenIterator() != null) { + return TextDiffType.deriveInstanceForInlineWrapperFragment(type); + } + return type; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java index fad3114dcec7..674d70b8d0b3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/fragments/FragmentHighlighterImpl.java @@ -49,6 +49,8 @@ public class FragmentHighlighterImpl implements FragmentHighlighter { } public void highlightLine(final LineFragment fragment) { + highlightFragmentImpl(fragment); + addModifyActions(fragment, myAppender1, myAppender2); final Iterator iterator = fragment.getChildrenIterator(); if (iterator == null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java index 4247184c7240..06d1bc744dfa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java @@ -21,9 +21,11 @@ import com.intellij.openapi.diff.DiffColors; import com.intellij.openapi.diff.actions.MergeActionGroup; import com.intellij.openapi.diff.actions.MergeOperations; import com.intellij.openapi.diff.impl.DiffLineMarkerRenderer; +import com.intellij.openapi.diff.impl.DiffUtil; import com.intellij.openapi.diff.impl.EditorSource; import com.intellij.openapi.diff.impl.fragments.Fragment; import com.intellij.openapi.diff.impl.fragments.InlineFragment; +import com.intellij.openapi.diff.impl.fragments.LineFragment; import com.intellij.openapi.diff.impl.util.GutterActionRenderer; import com.intellij.openapi.diff.impl.util.TextDiffType; import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum; @@ -69,14 +71,16 @@ public abstract class DiffMarkup implements EditorSource, Disposable { public void highlightText(@NotNull Fragment fragment, @Nullable GutterIconRenderer gutterIconRenderer) { MarkupModel markupModel = getMarkupModel(); - Editor editor = getEditor(); + EditorEx editor = getEditor(); TextDiffTypeEnum diffTypeEnum = fragment.getType(); if (diffTypeEnum == null || markupModel == null || editor == null) { return; } - TextDiffType type = TextDiffType.create(diffTypeEnum); + TextDiffType type = fragment instanceof LineFragment + ? DiffUtil.makeTextDiffType((LineFragment)fragment) + : TextDiffType.create(diffTypeEnum); TextRange range = fragment.getRange(getSide()); - TextAttributes attributes = type.getTextAttributes(getEditor()); + TextAttributes attributes = type.getTextAttributes(editor); if (attributes == null) { return; } @@ -95,23 +99,18 @@ public abstract class DiffMarkup implements EditorSource, Disposable { rangeMarker.setGutterIconRenderer(gutterIconRenderer); } - boolean adjustHeight = shouldIncreaseHighlightingHeight(fragment); - rangeMarker.setLineMarkerRenderer(adjustHeight - ? DiffLineMarkerRenderer.createHeightAdjustingInstance(type, range) - : DiffLineMarkerRenderer.createStandardInstance(type)); + if (!(fragment instanceof InlineFragment)) { + rangeMarker.setLineMarkerRenderer(DiffLineMarkerRenderer.createInstance(type)); - Color stripeBarColor = attributes.getErrorStripeColor(); - if (stripeBarColor != null) { - rangeMarker.setErrorStripeMarkColor(stripeBarColor); - rangeMarker.setThinErrorStripeMark(true); + Color stripeBarColor = attributes.getErrorStripeColor(); + if (stripeBarColor != null) { + rangeMarker.setErrorStripeMarkColor(stripeBarColor); + rangeMarker.setThinErrorStripeMark(true); + } } saveHighlighter(rangeMarker); } - private static boolean shouldIncreaseHighlightingHeight(@NotNull Fragment fragment) { - return fragment instanceof InlineFragment; - } - public void addLineMarker(int line, @Nullable TextAttributesKey type) { RangeHighlighter marker = createLineMarker(type, line); if (marker == null) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java index 89a1f3dcf568..b5aa64bbfd45 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java @@ -78,7 +78,7 @@ class ChangeHighlighterHolder { RangeHighlighter highlighter = getMarkupModel().addLineHighlighter(line, layer, null); highlighter.setLineSeparatorColor(diffType.getTextBackground(myEditor)); highlighterCreated(highlighter, diffType.getTextAttributes(myEditor), applied); - highlighter.setLineMarkerRenderer(DiffLineMarkerRenderer.createStandardInstance(diffType)); + highlighter.setLineMarkerRenderer(DiffLineMarkerRenderer.createInstance(diffType)); return highlighter; } @@ -89,7 +89,7 @@ class ChangeHighlighterHolder { TextAttributes attributes = type.getTextAttributes(myEditor); RangeHighlighter highlighter = getMarkupModel().addRangeHighlighter(start, end, layer, attributes, targetArea); highlighterCreated(highlighter, attributes, applied); - highlighter.setLineMarkerRenderer(DiffLineMarkerRenderer.createStandardInstance(type)); + highlighter.setLineMarkerRenderer(DiffLineMarkerRenderer.createInstance(type)); return highlighter; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/LineBlocks.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/LineBlocks.java index 22ce1f403eb8..3046c873f41a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/LineBlocks.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/LineBlocks.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.splitter; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.DiffUtil; import com.intellij.openapi.diff.impl.fragments.LineBlock; import com.intellij.openapi.diff.impl.fragments.LineFragment; import com.intellij.openapi.diff.impl.highlighting.FragmentSide; @@ -178,11 +179,19 @@ public class LineBlocks { for (LineBlock block : blocks) { Interval interval1 = new Interval(block.getStartingLine1(), block.getModifiedLines1()); Interval interval2 = new Interval(block.getStartingLine2(), block.getModifiedLines2()); - diffs.add(new Diff(interval1, interval2, TextDiffType.create(block.getType()))); + diffs.add(new Diff(interval1, interval2, makeTextDiffType(block))); } return new LineBlocks(diffs); } + private static TextDiffType makeTextDiffType(LineBlock block) { + TextDiffType type = TextDiffType.create(block.getType()); + if (block instanceof LineFragment) { + return DiffUtil.makeTextDiffType((LineFragment)block); + } + return type; + } + @NotNull public static LineBlocks fromChanges(@NotNull List changes) { // changes may come mixed, need to sort them to get correct intervals diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java index c72c0f92028e..29f4f97fafa1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diff.ex.DiffStatusBar; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.util.containers.Convertor; import org.jetbrains.annotations.NotNull; @@ -46,16 +47,22 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor { return textDiffType.getAttributesKey(); } }; + private static final double MIDDLE_COLOR_FACTOR = 0.6; private final TextDiffTypeEnum myType; private final TextAttributesKey myAttributesKey; private final String myDisplayName; private final boolean myApplied; + private final boolean myInlineWrapper; public boolean isApplied() { return myApplied; } + public boolean isInlineWrapper() { + return myInlineWrapper; + } + @NotNull public static TextDiffType create(@Nullable final TextDiffTypeEnum type) { if (TextDiffTypeEnum.INSERT.equals(type)) { @@ -78,18 +85,24 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor { */ @NotNull public static TextDiffType deriveApplied(@NotNull TextDiffType source) { - return new TextDiffType(source.myType, source.myDisplayName, source.myAttributesKey, true); + return new TextDiffType(source.myType, source.myDisplayName, source.myAttributesKey, true, false); + } + + public static TextDiffType deriveInstanceForInlineWrapperFragment(@NotNull TextDiffType source) { + return new TextDiffType(source.myType, source.myDisplayName, source.myAttributesKey, source.myApplied, true); } private TextDiffType(TextDiffTypeEnum type, String displayName, TextAttributesKey attributesKey) { - this(type, displayName, attributesKey, false); + this(type, displayName, attributesKey, false, false); } - private TextDiffType(TextDiffTypeEnum type, String displayName, TextAttributesKey attributesKey, boolean applied) { + private TextDiffType(TextDiffTypeEnum type, String displayName, TextAttributesKey attributesKey, boolean applied, + boolean inlineWrapper) { myType = type; myAttributesKey = attributesKey; myDisplayName = displayName; myApplied = applied; + myInlineWrapper = inlineWrapper; } public String getDisplayName() { @@ -108,15 +121,7 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor { @Nullable public TextAttributes getTextAttributes(EditorColorsScheme scheme) { - TextAttributes originalAttrs = scheme.getAttributes(myAttributesKey); - if (originalAttrs == null) { - return null; - } - TextAttributes overridingAttributes = new TextAttributes(); - if (myApplied) { - overridingAttributes.setBackgroundColor(scheme.getDefaultBackground()); - } - return TextAttributes.merge(originalAttrs, overridingAttributes); + return scheme.getAttributes(myAttributesKey); } @Nullable @@ -124,15 +129,29 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor { if (isApplied()) { return getLegendColor(editor.getColorsScheme()); } + else if (isInlineWrapper()) { + return getBgColorForFragmentContainingInlines((EditorEx)editor); + } else { - TextAttributes attributes = getTextAttributes(editor.getColorsScheme()); + TextAttributes attributes = getTextAttributes(editor); return attributes == null ? null : attributes.getBackgroundColor(); } } @Nullable - public TextAttributes getTextAttributes(Editor editor) { - return getTextAttributes(editor.getColorsScheme()); + public TextAttributes getTextAttributes(@NotNull Editor editor) { + TextAttributes originalAttrs = getTextAttributes(editor.getColorsScheme()); + if (originalAttrs == null) { + return null; + } + TextAttributes overridingAttributes = new TextAttributes(); + if (myApplied) { + overridingAttributes.setBackgroundColor(((EditorEx)editor).getBackgroundColor()); + } + else if (myInlineWrapper) { + overridingAttributes.setBackgroundColor(getBgColorForFragmentContainingInlines((EditorEx)editor)); + } + return TextAttributes.merge(originalAttrs, overridingAttributes); } @Nullable @@ -149,4 +168,30 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor { return myType; } + @Nullable + private Color getBgColorForFragmentContainingInlines(@NotNull EditorEx editor) { + TextAttributes originalAttrs = getTextAttributes(editor.getColorsScheme()); + if (originalAttrs == null) { + return null; + } + Color fg = originalAttrs.getBackgroundColor(); + if (fg == null) { + return null; + } + Color bg = editor.getBackgroundColor(); + return getMiddleColor(fg, bg, MIDDLE_COLOR_FACTOR); + } + + @NotNull + private static Color getMiddleColor(Color fg, Color bg, double factor) { + int red = avg(fg.getRed(), bg.getRed(), factor); + int green = avg(fg.getGreen(), bg.getGreen(), factor); + int blue = avg(fg.getBlue(), bg.getBlue(), factor); + return new Color(red, green, blue); + } + + private static int avg(int fg, int bg, double factor) { + return (int)(fg + Math.round(factor * (bg - fg))); + } + }