| /* |
| * Copyright 2000-2010 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.fragments; |
| |
| import com.intellij.openapi.diff.actions.MergeOperations; |
| import com.intellij.openapi.diff.impl.DiffUtil; |
| import com.intellij.openapi.diff.impl.highlighting.DiffMarkup; |
| import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum; |
| import com.intellij.openapi.editor.Document; |
| import com.intellij.openapi.editor.markup.SeparatorPlacement; |
| import com.intellij.openapi.util.TextRange; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.Iterator; |
| |
| public class FragmentHighlighterImpl implements FragmentHighlighter { |
| protected final DiffMarkup myAppender1; |
| protected final DiffMarkup myAppender2; |
| private boolean myIsLast; |
| |
| public FragmentHighlighterImpl(DiffMarkup appender1, DiffMarkup appender2) { |
| myAppender1 = appender1; |
| myAppender2 = appender2; |
| myIsLast = false; |
| } |
| |
| public void setIsLast(boolean isLast) { |
| myIsLast = isLast; |
| } |
| |
| public void highlightInline(final InlineFragment fragment) { |
| highlightFragmentImpl(fragment); |
| } |
| |
| protected void highlightFragmentImpl(final Fragment fragment) { |
| myAppender1.highlightText(fragment, null); |
| myAppender2.highlightText(fragment, null); |
| } |
| |
| public void highlightLine(final LineFragment fragment) { |
| highlightFragmentImpl(fragment); |
| |
| addModifyActions(fragment, myAppender1, myAppender2); |
| final Iterator<Fragment> iterator = fragment.getChildrenIterator(); |
| if (iterator != null) { |
| while (iterator.hasNext()) { |
| Fragment childFragment = iterator.next(); |
| childFragment.highlight(this); |
| } |
| } |
| if (fragment.isEqual() && myIsLast) return; |
| addSeparatingLine(fragment, myAppender1, fragment.getStartingLine1(), fragment.getEndLine1()); |
| addSeparatingLine(fragment, myAppender2, fragment.getStartingLine2(), fragment.getEndLine2()); |
| } |
| |
| private static void addModifyActions(final LineFragment fragment, DiffMarkup wrapper, DiffMarkup otherWrapper) { |
| if (fragment.isEqual()) return; |
| if (fragment.isHasLineChildren()) return; |
| TextRange range = fragment.getRange(wrapper.getSide()); |
| TextRange otherRange = fragment.getRange(wrapper.getSide().otherSide()); |
| Document document = wrapper.getDocument(); |
| Document otherDocument = otherWrapper.getDocument(); |
| wrapper.addAction(MergeOperations.mostSensible(document, otherDocument, range, otherRange), range.getStartOffset()); |
| otherWrapper.addAction(MergeOperations.mostSensible(otherDocument, document, otherRange, range), otherRange.getStartOffset()); |
| } |
| |
| private static void addSeparatingLine(@NotNull LineFragment fragment, @NotNull DiffMarkup appender, int startLine, int endLine) { |
| if (endLine <= 0) return; |
| TextDiffTypeEnum type = fragment.getType(); |
| appender.addLineMarker(endLine - 1, type == null ? null : DiffUtil.makeTextDiffType(fragment), SeparatorPlacement.BOTTOM); |
| if (fragment.getRange(appender.getSide()).getLength() > 0 && startLine > 0) { |
| appender.addLineMarker(startLine, type == null ? null : DiffUtil.makeTextDiffType(fragment), SeparatorPlacement.TOP); |
| } |
| } |
| } |