mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diff: refactor - extract model for SimpleDiffViewer
GitOrigin-RevId: 4e64d0ce809c17721e25ea8ffa6bbfa54a02537b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
724bdba465
commit
1c79fc589d
@@ -15,170 +15,44 @@
|
||||
*/
|
||||
package com.intellij.diff.tools.simple;
|
||||
|
||||
import com.intellij.diff.fragments.DiffFragment;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.util.*;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.diff.util.TextDiffType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleDiffChange {
|
||||
@NotNull protected final SimpleDiffViewer myViewer;
|
||||
private final int myIndex;
|
||||
|
||||
@NotNull private final LineFragment myFragment;
|
||||
@Nullable private final List<DiffFragment> myInnerFragments;
|
||||
private final boolean myIsExcluded;
|
||||
private final boolean myIsSkipped;
|
||||
|
||||
@NotNull protected final List<RangeHighlighter> myHighlighters = new ArrayList<>();
|
||||
@NotNull protected final List<GutterOperation> myOperations = new ArrayList<>();
|
||||
|
||||
private boolean myIsValid = true;
|
||||
private boolean myIsDestroyed = true;
|
||||
private final int[] myLineStartShifts = new int[2];
|
||||
private final int[] myLineEndShifts = new int[2];
|
||||
|
||||
public SimpleDiffChange(@NotNull SimpleDiffViewer viewer,
|
||||
public SimpleDiffChange(int index,
|
||||
@NotNull LineFragment fragment) {
|
||||
this(viewer, fragment, false, false);
|
||||
this(index, fragment, false, false);
|
||||
}
|
||||
|
||||
public SimpleDiffChange(@NotNull SimpleDiffViewer viewer,
|
||||
public SimpleDiffChange(int index,
|
||||
@NotNull LineFragment fragment,
|
||||
boolean isExcluded,
|
||||
boolean isSkipped) {
|
||||
myViewer = viewer;
|
||||
myIndex = index;
|
||||
|
||||
myFragment = fragment;
|
||||
myInnerFragments = fragment.getInnerFragments();
|
||||
myIsExcluded = isExcluded;
|
||||
myIsSkipped = isSkipped;
|
||||
}
|
||||
|
||||
public void installHighlighter(@Nullable LineFragment previousFragment) {
|
||||
assert myHighlighters.isEmpty();
|
||||
|
||||
if (myInnerFragments != null) {
|
||||
doInstallHighlighterWithInner();
|
||||
}
|
||||
else {
|
||||
doInstallHighlighterSimple();
|
||||
}
|
||||
doInstallNonSquashedChangesSeparator(previousFragment);
|
||||
|
||||
doInstallActionHighlighters();
|
||||
public int getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
public void destroyHighlighter() {
|
||||
for (RangeHighlighter highlighter : myHighlighters) {
|
||||
highlighter.dispose();
|
||||
}
|
||||
myHighlighters.clear();
|
||||
|
||||
for (GutterOperation operation : myOperations) {
|
||||
operation.dispose();
|
||||
}
|
||||
myOperations.clear();
|
||||
}
|
||||
|
||||
private void doInstallHighlighterSimple() {
|
||||
createHighlighter(Side.LEFT, false);
|
||||
createHighlighter(Side.RIGHT, false);
|
||||
}
|
||||
|
||||
private void doInstallHighlighterWithInner() {
|
||||
assert myInnerFragments != null;
|
||||
|
||||
createHighlighter(Side.LEFT, true);
|
||||
createHighlighter(Side.RIGHT, true);
|
||||
|
||||
for (DiffFragment fragment : myInnerFragments) {
|
||||
createInlineHighlighter(fragment, Side.LEFT);
|
||||
createInlineHighlighter(fragment, Side.RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
private void doInstallNonSquashedChangesSeparator(@Nullable LineFragment previousFragment) {
|
||||
createNonSquashedChangesSeparator(previousFragment, Side.LEFT);
|
||||
createNonSquashedChangesSeparator(previousFragment, Side.RIGHT);
|
||||
}
|
||||
|
||||
protected void doInstallActionHighlighters() {
|
||||
if (myIsSkipped) return;
|
||||
|
||||
myOperations.add(new AcceptGutterOperation(Side.LEFT));
|
||||
myOperations.add(new AcceptGutterOperation(Side.RIGHT));
|
||||
}
|
||||
|
||||
private void createHighlighter(@NotNull Side side, boolean ignored) {
|
||||
Editor editor = myViewer.getEditor(side);
|
||||
|
||||
TextDiffType type = DiffUtil.getLineDiffType(myFragment);
|
||||
int startLine = side.getStartLine(myFragment);
|
||||
int endLine = side.getEndLine(myFragment);
|
||||
|
||||
myHighlighters.addAll(new DiffDrawUtil.LineHighlighterBuilder(editor, startLine, endLine, type)
|
||||
.withIgnored(ignored)
|
||||
.withExcludedInEditor(myIsSkipped)
|
||||
.withExcludedInGutter(myIsExcluded)
|
||||
.done());
|
||||
}
|
||||
|
||||
private void createInlineHighlighter(@NotNull DiffFragment fragment, @NotNull Side side) {
|
||||
if (myIsSkipped) return;
|
||||
|
||||
int start = side.getStartOffset(fragment);
|
||||
int end = side.getEndOffset(fragment);
|
||||
TextDiffType type = DiffUtil.getDiffType(fragment);
|
||||
|
||||
int startOffset = side.getStartOffset(myFragment);
|
||||
start += startOffset;
|
||||
end += startOffset;
|
||||
|
||||
Editor editor = myViewer.getEditor(side);
|
||||
myHighlighters.addAll(DiffDrawUtil.createInlineHighlighter(editor, start, end, type));
|
||||
}
|
||||
|
||||
private void createNonSquashedChangesSeparator(@Nullable LineFragment previousFragment, @NotNull Side side) {
|
||||
if (previousFragment == null) return;
|
||||
|
||||
int startLine = side.getStartLine(myFragment);
|
||||
int endLine = side.getEndLine(myFragment);
|
||||
|
||||
int prevStartLine = side.getStartLine(previousFragment);
|
||||
int prevEndLine = side.getEndLine(previousFragment);
|
||||
|
||||
if (startLine == endLine) return;
|
||||
if (prevStartLine == prevEndLine) return;
|
||||
if (prevEndLine != startLine) return;
|
||||
|
||||
myHighlighters.addAll(DiffDrawUtil.createLineMarker(myViewer.getEditor(side), startLine, TextDiffType.MODIFIED));
|
||||
}
|
||||
|
||||
public void updateGutterActions(boolean force) {
|
||||
for (GutterOperation operation : myOperations) {
|
||||
operation.update(force);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Getters
|
||||
//
|
||||
|
||||
public int getStartLine(@NotNull Side side) {
|
||||
return side.getStartLine(myFragment) + side.select(myLineStartShifts);
|
||||
}
|
||||
@@ -204,16 +78,16 @@ public class SimpleDiffChange {
|
||||
return myIsValid;
|
||||
}
|
||||
|
||||
public boolean isDestroyed() {
|
||||
return myIsDestroyed;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineFragment getFragment() {
|
||||
return myFragment;
|
||||
}
|
||||
|
||||
//
|
||||
// Shift
|
||||
//
|
||||
|
||||
public boolean processChange(int oldLine1, int oldLine2, int shift, @NotNull Side side) {
|
||||
public boolean processDocumentChange(int oldLine1, int oldLine2, int shift, @NotNull Side side) {
|
||||
int line1 = getStartLine(side);
|
||||
int line2 = getEndLine(side);
|
||||
int sideIndex = side.getIndex();
|
||||
@@ -223,124 +97,13 @@ public class SimpleDiffChange {
|
||||
myLineEndShifts[sideIndex] += newRange.endLine - line2;
|
||||
|
||||
if (newRange.damaged) {
|
||||
for (GutterOperation operation : myOperations) {
|
||||
operation.dispose();
|
||||
}
|
||||
myOperations.clear();
|
||||
|
||||
myIsValid = false;
|
||||
}
|
||||
|
||||
return newRange.damaged;
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
protected abstract class GutterOperation {
|
||||
@NotNull protected final Side mySide;
|
||||
@NotNull private final RangeHighlighter myHighlighter;
|
||||
|
||||
protected boolean myCtrlPressed;
|
||||
|
||||
public GutterOperation(@NotNull Side side) {
|
||||
mySide = side;
|
||||
|
||||
int offset = side.getStartOffset(myFragment);
|
||||
EditorEx editor = myViewer.getEditor(side);
|
||||
myHighlighter = editor.getMarkupModel().addRangeHighlighter(offset, offset,
|
||||
HighlighterLayer.ADDITIONAL_SYNTAX,
|
||||
null,
|
||||
HighlighterTargetArea.LINES_IN_RANGE);
|
||||
|
||||
update(true);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
myHighlighter.dispose();
|
||||
}
|
||||
|
||||
public void update(boolean force) {
|
||||
if (!force && !areModifiersChanged()) {
|
||||
return;
|
||||
}
|
||||
if (myHighlighter.isValid()) myHighlighter.setGutterIconRenderer(createRenderer());
|
||||
}
|
||||
|
||||
private boolean areModifiersChanged() {
|
||||
return myCtrlPressed != myViewer.getModifierProvider().isCtrlPressed();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract GutterIconRenderer createRenderer();
|
||||
}
|
||||
|
||||
private class AcceptGutterOperation extends GutterOperation {
|
||||
AcceptGutterOperation(@NotNull Side side) {
|
||||
super(side);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GutterIconRenderer createRenderer() {
|
||||
myCtrlPressed = myViewer.getModifierProvider().isCtrlPressed();
|
||||
|
||||
boolean isOtherEditable = DiffUtil.isEditable(myViewer.getEditor(mySide.other()));
|
||||
boolean isAppendable = myFragment.getStartLine1() != myFragment.getEndLine1() &&
|
||||
myFragment.getStartLine2() != myFragment.getEndLine2();
|
||||
|
||||
if (isOtherEditable) {
|
||||
if (myCtrlPressed && isAppendable) {
|
||||
return createAppendRenderer(mySide);
|
||||
}
|
||||
else {
|
||||
return createApplyRenderer(mySide);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GutterIconRenderer createApplyRenderer(@NotNull final Side side) {
|
||||
String text;
|
||||
Icon icon = DiffUtil.getArrowIcon(side);
|
||||
|
||||
if (side == Side.LEFT && myViewer.isDiffForLocalChanges()) {
|
||||
text = "Revert";
|
||||
}
|
||||
else {
|
||||
text = "Accept";
|
||||
}
|
||||
|
||||
String actionId = side.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide");
|
||||
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
|
||||
String shortcutsText = StringUtil.nullize(KeymapUtil.getShortcutsText(shortcuts));
|
||||
String tooltipText = DiffUtil.createTooltipText(text, shortcutsText);
|
||||
|
||||
return createIconRenderer(side, tooltipText, icon, () -> myViewer.replaceChange(this, side));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GutterIconRenderer createAppendRenderer(@NotNull final Side side) {
|
||||
return createIconRenderer(side, "Append", DiffUtil.getArrowDownIcon(side), () -> myViewer.appendChange(this, side));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GutterIconRenderer createIconRenderer(@NotNull final Side sourceSide,
|
||||
@NotNull final String tooltipText,
|
||||
@NotNull final Icon icon,
|
||||
@NotNull final Runnable perform) {
|
||||
if (!DiffUtil.isEditable(myViewer.getEditor(sourceSide.other()))) return null;
|
||||
return new DiffGutterRenderer(icon, tooltipText) {
|
||||
@Override
|
||||
protected void handleMouseClick() {
|
||||
if (!myIsValid) return;
|
||||
final Project project = myViewer.getProject();
|
||||
final Document document = myViewer.getEditor(sourceSide.other()).getDocument();
|
||||
DiffUtil.executeWriteCommand(document, project, "Replace change", perform);
|
||||
}
|
||||
};
|
||||
public void markDestroyed() {
|
||||
myIsDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.diff.tools.simple;
|
||||
|
||||
import com.intellij.diff.fragments.DiffFragment;
|
||||
import com.intellij.diff.util.*;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleDiffChangeUi {
|
||||
@NotNull protected final SimpleDiffViewer myViewer;
|
||||
@NotNull protected final SimpleDiffChange myChange;
|
||||
|
||||
@NotNull protected final List<RangeHighlighter> myHighlighters = new ArrayList<>();
|
||||
@NotNull protected final List<GutterOperation> myOperations = new ArrayList<>();
|
||||
|
||||
public SimpleDiffChangeUi(@NotNull SimpleDiffViewer viewer, @NotNull SimpleDiffChange change) {
|
||||
myViewer = viewer;
|
||||
myChange = change;
|
||||
}
|
||||
|
||||
public void installHighlighter(@Nullable SimpleDiffChange previousChange) {
|
||||
assert myHighlighters.isEmpty();
|
||||
|
||||
List<DiffFragment> innerFragments = myChange.getFragment().getInnerFragments();
|
||||
if (innerFragments != null) {
|
||||
doInstallHighlighterWithInner(innerFragments);
|
||||
}
|
||||
else {
|
||||
doInstallHighlighterSimple();
|
||||
}
|
||||
doInstallNonSquashedChangesSeparator(previousChange);
|
||||
|
||||
doInstallActionHighlighters();
|
||||
}
|
||||
|
||||
public void destroyHighlighter() {
|
||||
for (RangeHighlighter highlighter : myHighlighters) {
|
||||
highlighter.dispose();
|
||||
}
|
||||
myHighlighters.clear();
|
||||
|
||||
for (GutterOperation operation : myOperations) {
|
||||
operation.dispose();
|
||||
}
|
||||
myOperations.clear();
|
||||
}
|
||||
|
||||
private void doInstallHighlighterSimple() {
|
||||
createHighlighter(Side.LEFT, false);
|
||||
createHighlighter(Side.RIGHT, false);
|
||||
}
|
||||
|
||||
private void doInstallHighlighterWithInner(@NotNull List<DiffFragment> innerFragments) {
|
||||
createHighlighter(Side.LEFT, true);
|
||||
createHighlighter(Side.RIGHT, true);
|
||||
|
||||
for (DiffFragment fragment : innerFragments) {
|
||||
createInlineHighlighter(fragment, Side.LEFT);
|
||||
createInlineHighlighter(fragment, Side.RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
private void doInstallNonSquashedChangesSeparator(@Nullable SimpleDiffChange previousChange) {
|
||||
createNonSquashedChangesSeparator(previousChange, Side.LEFT);
|
||||
createNonSquashedChangesSeparator(previousChange, Side.RIGHT);
|
||||
}
|
||||
|
||||
protected void doInstallActionHighlighters() {
|
||||
if (myChange.isSkipped()) return;
|
||||
|
||||
myOperations.add(new AcceptGutterOperation(Side.LEFT));
|
||||
myOperations.add(new AcceptGutterOperation(Side.RIGHT));
|
||||
}
|
||||
|
||||
private void createHighlighter(@NotNull Side side, boolean ignored) {
|
||||
Editor editor = myViewer.getEditor(side);
|
||||
|
||||
TextDiffType type = myChange.getDiffType();
|
||||
int startLine = myChange.getStartLine(side);
|
||||
int endLine = myChange.getEndLine(side);
|
||||
|
||||
myHighlighters.addAll(new DiffDrawUtil.LineHighlighterBuilder(editor, startLine, endLine, type)
|
||||
.withIgnored(ignored)
|
||||
.withExcludedInEditor(myChange.isSkipped())
|
||||
.withExcludedInGutter(myChange.isExcluded())
|
||||
.done());
|
||||
}
|
||||
|
||||
private void createInlineHighlighter(@NotNull DiffFragment innerFragment, @NotNull Side side) {
|
||||
if (myChange.isSkipped()) return;
|
||||
|
||||
int start = side.getStartOffset(innerFragment);
|
||||
int end = side.getEndOffset(innerFragment);
|
||||
TextDiffType type = DiffUtil.getDiffType(innerFragment);
|
||||
|
||||
int startOffset = side.getStartOffset(myChange.getFragment());
|
||||
start += startOffset;
|
||||
end += startOffset;
|
||||
|
||||
Editor editor = myViewer.getEditor(side);
|
||||
myHighlighters.addAll(DiffDrawUtil.createInlineHighlighter(editor, start, end, type));
|
||||
}
|
||||
|
||||
private void createNonSquashedChangesSeparator(@Nullable SimpleDiffChange previousChange, @NotNull Side side) {
|
||||
if (previousChange == null) return;
|
||||
|
||||
int startLine = myChange.getStartLine(side);
|
||||
int endLine = myChange.getEndLine(side);
|
||||
|
||||
int prevStartLine = previousChange.getStartLine(side);
|
||||
int prevEndLine = previousChange.getEndLine(side);
|
||||
|
||||
if (startLine == endLine) return;
|
||||
if (prevStartLine == prevEndLine) return;
|
||||
if (prevEndLine != startLine) return;
|
||||
|
||||
myHighlighters.addAll(DiffDrawUtil.createLineMarker(myViewer.getEditor(side), startLine, TextDiffType.MODIFIED));
|
||||
}
|
||||
|
||||
public void updateGutterActions(boolean force) {
|
||||
for (GutterOperation operation : myOperations) {
|
||||
operation.update(force);
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
for (GutterOperation operation : myOperations) {
|
||||
operation.dispose();
|
||||
}
|
||||
myOperations.clear();
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
protected abstract class GutterOperation {
|
||||
@NotNull protected final Side mySide;
|
||||
@NotNull private final RangeHighlighter myHighlighter;
|
||||
|
||||
protected boolean myCtrlPressed;
|
||||
|
||||
public GutterOperation(@NotNull Side side) {
|
||||
mySide = side;
|
||||
|
||||
int offset = side.getStartOffset(myChange.getFragment());
|
||||
EditorEx editor = myViewer.getEditor(side);
|
||||
myHighlighter = editor.getMarkupModel().addRangeHighlighter(offset, offset,
|
||||
HighlighterLayer.ADDITIONAL_SYNTAX,
|
||||
null,
|
||||
HighlighterTargetArea.LINES_IN_RANGE);
|
||||
|
||||
update(true);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
myHighlighter.dispose();
|
||||
}
|
||||
|
||||
public void update(boolean force) {
|
||||
if (!force && !areModifiersChanged()) {
|
||||
return;
|
||||
}
|
||||
if (myHighlighter.isValid()) myHighlighter.setGutterIconRenderer(createRenderer());
|
||||
}
|
||||
|
||||
private boolean areModifiersChanged() {
|
||||
return myCtrlPressed != myViewer.getModifierProvider().isCtrlPressed();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract GutterIconRenderer createRenderer();
|
||||
}
|
||||
|
||||
private class AcceptGutterOperation extends GutterOperation {
|
||||
AcceptGutterOperation(@NotNull Side side) {
|
||||
super(side);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GutterIconRenderer createRenderer() {
|
||||
myCtrlPressed = myViewer.getModifierProvider().isCtrlPressed();
|
||||
|
||||
boolean isOtherEditable = DiffUtil.isEditable(myViewer.getEditor(mySide.other()));
|
||||
boolean isAppendable = myChange.getDiffType() == TextDiffType.MODIFIED;
|
||||
|
||||
if (isOtherEditable) {
|
||||
if (myCtrlPressed && isAppendable) {
|
||||
return createAppendRenderer(mySide);
|
||||
}
|
||||
else {
|
||||
return createApplyRenderer(mySide);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GutterIconRenderer createApplyRenderer(@NotNull final Side side) {
|
||||
String text;
|
||||
Icon icon = DiffUtil.getArrowIcon(side);
|
||||
|
||||
if (side == Side.LEFT && myViewer.isDiffForLocalChanges()) {
|
||||
text = "Revert";
|
||||
}
|
||||
else {
|
||||
text = "Accept";
|
||||
}
|
||||
|
||||
String actionId = side.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide");
|
||||
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
|
||||
String shortcutsText = StringUtil.nullize(KeymapUtil.getShortcutsText(shortcuts));
|
||||
String tooltipText = DiffUtil.createTooltipText(text, shortcutsText);
|
||||
|
||||
return createIconRenderer(side, tooltipText, icon, () -> myViewer.replaceChange(myChange, side));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GutterIconRenderer createAppendRenderer(@NotNull final Side side) {
|
||||
return createIconRenderer(side, "Append", DiffUtil.getArrowDownIcon(side), () -> myViewer.appendChange(myChange, side));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GutterIconRenderer createIconRenderer(@NotNull final Side sourceSide,
|
||||
@NotNull final String tooltipText,
|
||||
@NotNull final Icon icon,
|
||||
@NotNull final Runnable perform) {
|
||||
if (!DiffUtil.isEditable(myViewer.getEditor(sourceSide.other()))) return null;
|
||||
return new DiffGutterRenderer(icon, tooltipText) {
|
||||
@Override
|
||||
protected void handleMouseClick() {
|
||||
if (!myChange.isValid()) return;
|
||||
final Project project = myViewer.getProject();
|
||||
final Document document = myViewer.getEditor(sourceSide.other()).getDocument();
|
||||
DiffUtil.executeWriteCommand(document, project, "Replace change", perform);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.diff.tools.simple;
|
||||
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.LineRange;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleDiffModel {
|
||||
@NotNull private final SimpleDiffViewer myViewer;
|
||||
|
||||
@NotNull private final List<SimpleDiffChange> myValidChanges = new ArrayList<>();
|
||||
@NotNull private final List<SimpleDiffChange> myAllChanges = new ArrayList<>();
|
||||
@NotNull private ThreeState myIsContentsEqual = ThreeState.UNSURE;
|
||||
|
||||
@NotNull private final List<SimpleDiffChangeUi> myPresentations = new ArrayList<>();
|
||||
|
||||
public SimpleDiffModel(@NotNull SimpleDiffViewer viewer) {
|
||||
myViewer = viewer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ThreeState isContentsEqual() {
|
||||
return myIsContentsEqual;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<SimpleDiffChange> getChanges() {
|
||||
return myValidChanges;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<SimpleDiffChange> getAllChanges() {
|
||||
return ContainerUtil.filter(myAllChanges, it -> !it.isDestroyed());
|
||||
}
|
||||
|
||||
public void setChanges(@NotNull List<SimpleDiffChange> changes, boolean isContentsEqual) {
|
||||
clear();
|
||||
|
||||
for (int i = 0; i < changes.size(); i++) {
|
||||
SimpleDiffChange change = changes.get(i);
|
||||
SimpleDiffChange previousChange = i != 0 ? changes.get(i - 1) : null;
|
||||
|
||||
SimpleDiffChangeUi changeUi = myViewer.createUi(change);
|
||||
changeUi.installHighlighter(previousChange);
|
||||
myPresentations.add(changeUi);
|
||||
}
|
||||
|
||||
myValidChanges.addAll(changes);
|
||||
myAllChanges.addAll(changes);
|
||||
myIsContentsEqual = ThreeState.fromBoolean(isContentsEqual);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (SimpleDiffChangeUi changeUi : myPresentations) {
|
||||
changeUi.destroyHighlighter();
|
||||
}
|
||||
myValidChanges.clear();
|
||||
myAllChanges.clear();
|
||||
myPresentations.clear();
|
||||
myIsContentsEqual = ThreeState.UNSURE;
|
||||
}
|
||||
|
||||
public void destroyChange(@NotNull SimpleDiffChange change) {
|
||||
SimpleDiffChangeUi changeUi = myPresentations.set(change.getIndex(), null);
|
||||
if (changeUi != null) changeUi.destroyHighlighter();
|
||||
|
||||
myValidChanges.remove(change);
|
||||
change.markDestroyed();
|
||||
}
|
||||
|
||||
public void updateGutterActions(boolean force) {
|
||||
for (SimpleDiffChangeUi changeUi : myPresentations) {
|
||||
changeUi.updateGutterActions(force);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleBeforeDocumentChange(@NotNull Side side, @NotNull DocumentEvent e) {
|
||||
if (myValidChanges.isEmpty()) return;
|
||||
|
||||
LineRange lineRange = DiffUtil.getAffectedLineRange(e);
|
||||
int shift = DiffUtil.countLinesShift(e);
|
||||
|
||||
List<SimpleDiffChange> invalidated = new ArrayList<>();
|
||||
for (SimpleDiffChange change : myValidChanges) {
|
||||
if (change.processDocumentChange(lineRange.start, lineRange.end, shift, side)) {
|
||||
invalidated.add(change);
|
||||
|
||||
SimpleDiffChangeUi changeUi = myPresentations.get(change.getIndex());
|
||||
if (changeUi != null) changeUi.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
myValidChanges.removeAll(invalidated);
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
@@ -59,9 +60,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@NotNull private final PrevNextDifferenceIterable myPrevNextDifferenceIterable;
|
||||
@NotNull private final StatusPanel myStatusPanel;
|
||||
|
||||
@NotNull private final List<SimpleDiffChange> myDiffChanges = new ArrayList<>();
|
||||
@NotNull private final List<SimpleDiffChange> myInvalidDiffChanges = new ArrayList<>();
|
||||
private boolean myIsContentsEqual;
|
||||
@NotNull private final SimpleDiffModel myModel = new SimpleDiffModel(this);
|
||||
|
||||
@NotNull private final MyFoldingModel myFoldingModel;
|
||||
@NotNull private final MyInitialScrollHelper myInitialScrollHelper = new MyInitialScrollHelper();
|
||||
@@ -97,7 +96,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
@CalledInAwt
|
||||
protected void onDispose() {
|
||||
destroyChangedBlocks();
|
||||
myModel.clear();
|
||||
myFoldingModel.destroy();
|
||||
super.onDispose();
|
||||
}
|
||||
@@ -161,6 +160,11 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
myInitialScrollHelper.updateContext(myRequest);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected SimpleDiffChangeUi createUi(@NotNull SimpleDiffChange change) {
|
||||
return new SimpleDiffChangeUi(this, change);
|
||||
}
|
||||
|
||||
//
|
||||
// Diff
|
||||
//
|
||||
@@ -197,7 +201,10 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
return apply(null, isContentsEqual);
|
||||
}
|
||||
else {
|
||||
List<SimpleDiffChange> changes = ContainerUtil.map(lineFragments, fragment -> new SimpleDiffChange(this, fragment));
|
||||
List<SimpleDiffChange> changes = new ArrayList<>();
|
||||
for (LineFragment fragment : lineFragments) {
|
||||
changes.add(new SimpleDiffChange(changes.size(), fragment));
|
||||
}
|
||||
return apply(changes, isContentsEqual);
|
||||
}
|
||||
}
|
||||
@@ -224,22 +231,13 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
|
||||
clearDiffPresentation();
|
||||
|
||||
myIsContentsEqual = isContentsEqual;
|
||||
if (isContentsEqual) {
|
||||
boolean equalCharsets = TextDiffViewerUtil.areEqualCharsets(getContents());
|
||||
boolean equalSeparators = TextDiffViewerUtil.areEqualLineSeparators(getContents());
|
||||
myPanel.addNotification(DiffNotifications.createEqualContents(equalCharsets, equalSeparators));
|
||||
}
|
||||
|
||||
if (changes != null) {
|
||||
for (int i = 0; i < changes.size(); i++) {
|
||||
SimpleDiffChange change = changes.get(i);
|
||||
LineFragment previousChangeFragment = i != 0 ? changes.get(i - 1).getFragment() : null;
|
||||
change.installHighlighter(previousChangeFragment);
|
||||
}
|
||||
|
||||
myDiffChanges.addAll(changes);
|
||||
}
|
||||
myModel.setChanges(ContainerUtil.notNullize(changes), isContentsEqual);
|
||||
|
||||
myFoldingModel.install(foldingState, myRequest, getFoldingModelSettings());
|
||||
|
||||
@@ -260,37 +258,23 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
}
|
||||
|
||||
private void clearDiffPresentation() {
|
||||
myStatusPanel.setBusy(false);
|
||||
myModel.clear();
|
||||
|
||||
myPanel.resetNotifications();
|
||||
destroyChangedBlocks();
|
||||
myStatusPanel.setBusy(false);
|
||||
|
||||
myContentPanel.repaintDivider();
|
||||
myStatusPanel.update();
|
||||
}
|
||||
|
||||
//
|
||||
// Impl
|
||||
//
|
||||
|
||||
private void destroyChangedBlocks() {
|
||||
myIsContentsEqual = false;
|
||||
|
||||
for (SimpleDiffChange change : myDiffChanges) {
|
||||
change.destroyHighlighter();
|
||||
}
|
||||
myDiffChanges.clear();
|
||||
|
||||
for (SimpleDiffChange change : myInvalidDiffChanges) {
|
||||
change.destroyHighlighter();
|
||||
}
|
||||
myInvalidDiffChanges.clear();
|
||||
|
||||
myContentPanel.repaintDivider();
|
||||
myStatusPanel.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CalledInAwt
|
||||
protected void onBeforeDocumentChange(@NotNull DocumentEvent e) {
|
||||
super.onBeforeDocumentChange(e);
|
||||
if (myDiffChanges.isEmpty()) return;
|
||||
|
||||
List<Document> documents = ContainerUtil.map(getEditors(), Editor::getDocument);
|
||||
Side side = Side.fromValue(documents, e.getDocument());
|
||||
@@ -299,26 +283,13 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
return;
|
||||
}
|
||||
|
||||
LineRange lineRange = DiffUtil.getAffectedLineRange(e);
|
||||
int shift = DiffUtil.countLinesShift(e);
|
||||
|
||||
List<SimpleDiffChange> invalid = new ArrayList<>();
|
||||
for (SimpleDiffChange change : myDiffChanges) {
|
||||
if (change.processChange(lineRange.start, lineRange.end, shift, side)) {
|
||||
invalid.add(change);
|
||||
}
|
||||
}
|
||||
|
||||
if (!invalid.isEmpty()) {
|
||||
myDiffChanges.removeAll(invalid);
|
||||
myInvalidDiffChanges.addAll(invalid);
|
||||
}
|
||||
myModel.handleBeforeDocumentChange(side, e);
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected boolean doScrollToChange(@NotNull ScrollToPolicy scrollToPolicy) {
|
||||
SimpleDiffChange targetChange = scrollToPolicy.select(getNonSkippedDiffChanges());
|
||||
if (targetChange == null) targetChange = scrollToPolicy.select(myDiffChanges);
|
||||
if (targetChange == null) targetChange = scrollToPolicy.select(getDiffChanges());
|
||||
if (targetChange == null) return false;
|
||||
|
||||
doScrollToChange(targetChange, false);
|
||||
@@ -358,12 +329,12 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
|
||||
@NotNull
|
||||
protected List<SimpleDiffChange> getDiffChanges() {
|
||||
return myDiffChanges;
|
||||
return myModel.getChanges();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<SimpleDiffChange> getNonSkippedDiffChanges() {
|
||||
return ContainerUtil.filter(myDiffChanges, it -> !it.isSkipped());
|
||||
return ContainerUtil.filter(myModel.getChanges(), it -> !it.isSkipped());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -409,10 +380,11 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
}
|
||||
|
||||
protected boolean isSomeChangeSelected(@NotNull Side side) {
|
||||
if (myDiffChanges.isEmpty()) return false;
|
||||
if (getDiffChanges().isEmpty()) return false;
|
||||
|
||||
EditorEx editor = getEditor(side);
|
||||
return DiffUtil.isSomeRangeSelected(editor, lines -> ContainerUtil.exists(myDiffChanges, change -> isChangeSelected(change, lines, side)));
|
||||
return DiffUtil.isSomeRangeSelected(editor, lines ->
|
||||
ContainerUtil.exists(getDiffChanges(), change -> isChangeSelected(change, lines, side)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -420,7 +392,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
protected List<SimpleDiffChange> getSelectedChanges(@NotNull Side side) {
|
||||
EditorEx editor = getEditor(side);
|
||||
BitSet lines = DiffUtil.getSelectedLines(editor);
|
||||
return ContainerUtil.filter(myDiffChanges, change -> isChangeSelected(change, lines, side));
|
||||
return ContainerUtil.filter(getDiffChanges(), change -> isChangeSelected(change, lines, side));
|
||||
}
|
||||
|
||||
private static boolean isChangeSelected(SimpleDiffChange change, @NotNull BitSet lines, @NotNull Side side) {
|
||||
@@ -434,7 +406,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
protected SimpleDiffChange getSelectedChange(@NotNull Side side) {
|
||||
int caretLine = getEditor(side).getCaretModel().getLogicalPosition().line;
|
||||
|
||||
for (SimpleDiffChange change : myDiffChanges) {
|
||||
for (SimpleDiffChange change : getDiffChanges()) {
|
||||
int line1 = change.getStartLine(side);
|
||||
int line2 = change.getEndLine(side);
|
||||
|
||||
@@ -484,9 +456,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
protected void doApply(boolean readOnly) {
|
||||
super.doApply(readOnly);
|
||||
for (SimpleDiffChange change : myDiffChanges) {
|
||||
change.updateGutterActions(true);
|
||||
}
|
||||
myModel.updateGutterActions(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,8 +601,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
DiffUtil.applyModification(getEditor(outputSide).getDocument(), change.getStartLine(outputSide), change.getEndLine(outputSide),
|
||||
getEditor(sourceSide).getDocument(), change.getStartLine(sourceSide), change.getEndLine(sourceSide));
|
||||
|
||||
change.destroyHighlighter();
|
||||
myDiffChanges.remove(change);
|
||||
myModel.destroyChange(change);
|
||||
}
|
||||
|
||||
@CalledWithWriteLock
|
||||
@@ -644,8 +613,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
DiffUtil.applyModification(getEditor(outputSide).getDocument(), change.getEndLine(outputSide), change.getEndLine(outputSide),
|
||||
getEditor(sourceSide).getDocument(), change.getStartLine(sourceSide), change.getEndLine(sourceSide));
|
||||
|
||||
change.destroyHighlighter();
|
||||
myDiffChanges.remove(change);
|
||||
myModel.destroyChange(change);
|
||||
}
|
||||
|
||||
private class MyToggleExpandByDefaultAction extends TextDiffViewerUtil.ToggleExpandByDefaultAction {
|
||||
@@ -672,12 +640,12 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
|
||||
@Override
|
||||
public boolean hasNextBlock() {
|
||||
return myIndex < myDiffChanges.size();
|
||||
return myIndex < getDiffChanges().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadNextBlock() {
|
||||
SimpleDiffChange change = myDiffChanges.get(myIndex);
|
||||
SimpleDiffChange change = getDiffChanges().get(myIndex);
|
||||
myIndex++;
|
||||
|
||||
int line1 = change.getStartLine(Side.RIGHT);
|
||||
@@ -723,14 +691,14 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@NotNull
|
||||
@Override
|
||||
public Range getRange(@NotNull Side baseSide, int line) {
|
||||
if (myDiffChanges.isEmpty()) return idRange(line);
|
||||
if (getDiffChanges().isEmpty()) return idRange(line);
|
||||
return super.getRange(baseSide, line);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHelper(@NotNull ScrollHelper helper) {
|
||||
if (!helper.process(0, 0)) return;
|
||||
for (SimpleDiffChange diffChange : myDiffChanges) {
|
||||
for (SimpleDiffChange diffChange : getDiffChanges()) {
|
||||
if (!helper.process(diffChange.getStartLine(Side.LEFT), diffChange.getStartLine(Side.RIGHT))) return;
|
||||
if (!helper.process(diffChange.getEndLine(Side.LEFT), diffChange.getEndLine(Side.RIGHT))) return;
|
||||
}
|
||||
@@ -755,7 +723,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
|
||||
@Override
|
||||
public void process(@NotNull Handler handler) {
|
||||
for (SimpleDiffChange diffChange : myDiffChanges) {
|
||||
for (SimpleDiffChange diffChange : getDiffChanges()) {
|
||||
if (!handler.processExcludable(diffChange.getStartLine(Side.LEFT), diffChange.getEndLine(Side.LEFT),
|
||||
diffChange.getStartLine(Side.RIGHT), diffChange.getEndLine(Side.RIGHT),
|
||||
getEditor1(), diffChange.getDiffType(), diffChange.isExcluded())) {
|
||||
@@ -772,10 +740,10 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
if (myTextDiffProvider.isHighlightingDisabled()) {
|
||||
return DiffBundle.message("diff.highlighting.disabled.text");
|
||||
}
|
||||
int excludedChanges = ContainerUtil.count(myDiffChanges, it -> it.isExcluded()) +
|
||||
ContainerUtil.count(myInvalidDiffChanges, it -> it.isExcluded());
|
||||
int changesCount = myDiffChanges.size() + myInvalidDiffChanges.size();
|
||||
if (changesCount == 0 && !myIsContentsEqual) {
|
||||
List<SimpleDiffChange> allChanges = myModel.getAllChanges();
|
||||
int excludedChanges = ContainerUtil.count(allChanges, it -> it.isExcluded());
|
||||
int changesCount = allChanges.size();
|
||||
if (changesCount == 0 && myModel.isContentsEqual() == ThreeState.NO) {
|
||||
return DiffBundle.message("diff.all.differences.ignored.text");
|
||||
}
|
||||
String message = DiffBundle.message("diff.count.differences.status.text", changesCount - excludedChanges);
|
||||
@@ -791,9 +759,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
|
||||
@Override
|
||||
public void onModifiersChanged() {
|
||||
for (SimpleDiffChange change : myDiffChanges) {
|
||||
change.updateGutterActions(false);
|
||||
}
|
||||
myModel.updateGutterActions(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-20
@@ -5,6 +5,7 @@ import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.comparison.DiffTooBigException;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.tools.simple.SimpleDiffChange;
|
||||
import com.intellij.diff.tools.simple.SimpleDiffChangeUi;
|
||||
import com.intellij.diff.tools.simple.SimpleDiffViewer;
|
||||
import com.intellij.diff.tools.util.DiffNotifications;
|
||||
import com.intellij.diff.util.DiffGutterRenderer;
|
||||
@@ -114,6 +115,13 @@ public class SimpleLocalChangeListDiffViewer extends SimpleDiffViewer {
|
||||
return group;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected SimpleDiffChangeUi createUi(@NotNull SimpleDiffChange change) {
|
||||
if (change instanceof MySimpleDiffChange) return new MySimpleDiffChangeUi(this, (MySimpleDiffChange)change);
|
||||
return super.createUi(change);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected Runnable performRediff(@NotNull final ProgressIndicator indicator) {
|
||||
@@ -218,7 +226,10 @@ public class SimpleLocalChangeListDiffViewer extends SimpleDiffViewer {
|
||||
boolean isSkipped = !isFromActiveChangelist;
|
||||
boolean isExcluded = !isFromActiveChangelist || (myAllowExcludeChangesFromCommit && isExcludedFromCommit);
|
||||
|
||||
changes.addAll(ContainerUtil.map(rangeFragments, fragment -> new MySimpleDiffChange(fragment, isExcluded, isSkipped, localRange.getChangelistId(), isExcludedFromCommit)));
|
||||
for (LineFragment fragment : rangeFragments) {
|
||||
changes.add(new MySimpleDiffChange(changes.size(), fragment, isExcluded, isSkipped,
|
||||
localRange.getChangelistId(), isFromActiveChangelist, isExcludedFromCommit));
|
||||
}
|
||||
}
|
||||
|
||||
return apply(changes, isContentsEqual);
|
||||
@@ -230,37 +241,57 @@ public class SimpleLocalChangeListDiffViewer extends SimpleDiffViewer {
|
||||
myExcludeAllCheckboxPanel.refresh();
|
||||
}
|
||||
|
||||
private class MySimpleDiffChange extends SimpleDiffChange {
|
||||
private static class MySimpleDiffChange extends SimpleDiffChange {
|
||||
@NotNull private final String myChangelistId;
|
||||
private final boolean myIsFromActiveChangelist;
|
||||
private final boolean myIsExcludedFromCommit;
|
||||
|
||||
MySimpleDiffChange(@NotNull LineFragment fragment,
|
||||
boolean isExcluded,
|
||||
boolean isSkipped,
|
||||
@NotNull String changelistId,
|
||||
boolean isExcludedFromCommit) {
|
||||
super(SimpleLocalChangeListDiffViewer.this, fragment, isExcluded, isSkipped);
|
||||
MySimpleDiffChange(int index,
|
||||
@NotNull LineFragment fragment,
|
||||
boolean isExcluded,
|
||||
boolean isSkipped,
|
||||
@NotNull String changelistId,
|
||||
boolean isFromActiveChangelist,
|
||||
boolean isExcludedFromCommit) {
|
||||
super(index, fragment, isExcluded, isSkipped);
|
||||
myChangelistId = changelistId;
|
||||
myIsFromActiveChangelist = isFromActiveChangelist;
|
||||
myIsExcludedFromCommit = isExcludedFromCommit;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getChangelistId() {
|
||||
return myChangelistId;
|
||||
}
|
||||
|
||||
public boolean isFromActiveChangelist() {
|
||||
return myIsFromActiveChangelist;
|
||||
}
|
||||
|
||||
public boolean isExcludedFromCommit() {
|
||||
return myIsExcludedFromCommit;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MySimpleDiffChangeUi extends SimpleDiffChangeUi {
|
||||
private MySimpleDiffChangeUi(@NotNull SimpleLocalChangeListDiffViewer viewer, @NotNull MySimpleDiffChange change) {
|
||||
super(viewer, change);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SimpleLocalChangeListDiffViewer getViewer() {
|
||||
return (SimpleLocalChangeListDiffViewer)myViewer;
|
||||
}
|
||||
|
||||
public boolean isFromActiveChangelist() {
|
||||
return myChangelistId.equals(getViewer().myChangelistId);
|
||||
}
|
||||
|
||||
public boolean isExcludedFromCommit() {
|
||||
return myIsExcludedFromCommit;
|
||||
@NotNull
|
||||
private MySimpleDiffChange getChange() {
|
||||
return ((MySimpleDiffChange)myChange);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInstallActionHighlighters() {
|
||||
super.doInstallActionHighlighters();
|
||||
if (myAllowExcludeChangesFromCommit && isFromActiveChangelist()) {
|
||||
if (getViewer().myAllowExcludeChangesFromCommit && getChange().isFromActiveChangelist()) {
|
||||
myOperations.add(new ExcludeGutterOperation());
|
||||
}
|
||||
}
|
||||
@@ -272,20 +303,21 @@ public class SimpleLocalChangeListDiffViewer extends SimpleDiffViewer {
|
||||
|
||||
@Override
|
||||
public GutterIconRenderer createRenderer() {
|
||||
if (!isFromActiveChangelist()) return null;
|
||||
if (!getChange().isFromActiveChangelist()) return null;
|
||||
|
||||
Icon icon = myIsExcludedFromCommit ? AllIcons.Diff.GutterCheckBox : AllIcons.Diff.GutterCheckBoxSelected;
|
||||
final boolean isExcludedFromCommit = getChange().isExcludedFromCommit();
|
||||
Icon icon = isExcludedFromCommit ? AllIcons.Diff.GutterCheckBox : AllIcons.Diff.GutterCheckBoxSelected;
|
||||
return new DiffGutterRenderer(icon, "Include into commit") {
|
||||
@Override
|
||||
protected void handleMouseClick() {
|
||||
if (!isValid()) return;
|
||||
if (!myChange.isValid()) return;
|
||||
|
||||
PartialLocalLineStatusTracker tracker = getViewer().getPartialTracker();
|
||||
if (tracker == null) return;
|
||||
LocalRange range = tracker.getRangeForLine(getStartLine(Side.RIGHT));
|
||||
LocalRange range = tracker.getRangeForLine(myChange.getStartLine(Side.RIGHT));
|
||||
if (range == null) return;
|
||||
|
||||
tracker.setExcludedFromCommit(range, !myIsExcludedFromCommit);
|
||||
tracker.setExcludedFromCommit(range, !isExcludedFromCommit);
|
||||
|
||||
getViewer().rediff();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user