IDEA-204040 diff: support changelists and excluded changes in unified viewer - add gutter checkbox

GitOrigin-RevId: eaba09eeefb1e27fb45d6eefce5185ee77ec6204
This commit is contained in:
Aleksey Pivovarov
2019-08-12 18:05:04 +03:00
committed by intellij-monorepo-bot
parent 2e0b731451
commit aa78744793
4 changed files with 96 additions and 37 deletions
@@ -21,12 +21,12 @@ import java.util.ArrayList;
import java.util.List;
public class UnifiedDiffChangeUi {
@NotNull private final UnifiedDiffViewer myViewer;
@NotNull private final EditorEx myEditor;
@NotNull private final UnifiedDiffChange myChange;
@NotNull protected final UnifiedDiffViewer myViewer;
@NotNull protected final EditorEx myEditor;
@NotNull protected final UnifiedDiffChange myChange;
@NotNull private final List<RangeHighlighter> myHighlighters = new ArrayList<>();
@NotNull private final List<MyGutterOperation> myOperations = new ArrayList<>();
@NotNull protected final List<RangeHighlighter> myHighlighters = new ArrayList<>();
@NotNull protected final List<MyGutterOperation> myOperations = new ArrayList<>();
public UnifiedDiffChangeUi(@NotNull UnifiedDiffViewer viewer, @NotNull UnifiedDiffChange change) {
myViewer = viewer;
@@ -53,7 +53,7 @@ public class UnifiedDiffChangeUi {
doInstallActionHighlighters();
}
private void doInstallActionHighlighters() {
protected void doInstallActionHighlighters() {
if (myChange.isSkipped()) return;
boolean leftEditable = myViewer.isEditable(Side.LEFT, false);
@@ -89,21 +89,32 @@ public class UnifiedDiffChangeUi {
@NotNull
private MyGutterOperation createOperation(@NotNull Side sourceSide) {
int offset = myEditor.getDocument().getLineStartOffset(myChange.getLine1());
RangeHighlighter highlighter = myEditor.getMarkupModel().addRangeHighlighter(offset, offset,
HighlighterLayer.ADDITIONAL_SYNTAX,
null,
HighlighterTargetArea.LINES_IN_RANGE);
return new MyGutterOperation(sourceSide, highlighter);
return new MyGutterOperation() {
@Nullable
@Override
public GutterIconRenderer createRenderer() {
if (myViewer.isStateIsOutOfDate()) return null;
if (!myViewer.isEditable(sourceSide.other(), true)) return null;
if (sourceSide.isLeft()) {
return createIconRenderer(sourceSide, "Revert", AllIcons.Diff.Remove);
}
else {
return createIconRenderer(sourceSide, "Accept", AllIcons.Actions.Checked);
}
}
};
}
private class MyGutterOperation {
@NotNull private final Side mySide;
protected abstract class MyGutterOperation {
@NotNull private final RangeHighlighter myHighlighter;
private MyGutterOperation(@NotNull Side sourceSide, @NotNull RangeHighlighter highlighter) {
mySide = sourceSide;
myHighlighter = highlighter;
public MyGutterOperation() {
int offset = myEditor.getDocument().getLineStartOffset(myChange.getLine1());
myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(offset, offset,
HighlighterLayer.ADDITIONAL_SYNTAX,
null,
HighlighterTargetArea.LINES_IN_RANGE);
update();
}
@@ -117,17 +128,7 @@ public class UnifiedDiffChangeUi {
}
@Nullable
public GutterIconRenderer createRenderer() {
if (myViewer.isStateIsOutOfDate()) return null;
if (!myViewer.isEditable(mySide.other(), true)) return null;
if (mySide.isLeft()) {
return createIconRenderer(mySide, "Revert", AllIcons.Diff.Remove);
}
else {
return createIconRenderer(mySide, "Accept", AllIcons.Actions.Checked);
}
}
public abstract GutterIconRenderer createRenderer();
}
private GutterIconRenderer createIconRenderer(@NotNull final Side sourceSide,
@@ -183,6 +183,15 @@ object LocalTrackerDiffUtil {
}
}
@JvmStatic
fun toggleRangeAtLine(provider: LocalTrackerActionProvider, line: Int, isExcludedFromCommit: Boolean) {
val tracker = provider.localRequest.partialTracker ?: return
val range = tracker.getRangeForLine(line) ?: return
tracker.setExcludedFromCommit(range, !isExcludedFromCommit)
provider.viewer.rediff()
}
@JvmStatic
fun createTrackerActions(provider: LocalTrackerActionProvider): List<AnAction> {
@@ -24,7 +24,6 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.actions.diff.lst.LocalTrackerDiffUtil.LocalTrackerChange;
import com.intellij.openapi.vcs.ex.ExclusionState;
import com.intellij.openapi.vcs.ex.LocalRange;
import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker;
import com.intellij.ui.InplaceButton;
import com.intellij.ui.scale.JBUIScale;
@@ -263,14 +262,8 @@ public class SimpleLocalChangeListDiffViewer extends SimpleDiffViewer {
protected void handleMouseClick() {
if (!myChange.isValid()) return;
PartialLocalLineStatusTracker tracker = getViewer().getPartialTracker();
if (tracker == null) return;
LocalRange range = tracker.getRangeForLine(myChange.getStartLine(Side.RIGHT));
if (range == null) return;
tracker.setExcludedFromCommit(range, !isExcludedFromCommit);
getViewer().rediff();
int line = myChange.getStartLine(Side.RIGHT);
LocalTrackerDiffUtil.toggleRangeAtLine(getViewer().myTrackerActionProvider, line, isExcludedFromCommit);
}
};
}
@@ -4,20 +4,25 @@ package com.intellij.openapi.vcs.changes.actions.diff.lst;
import com.intellij.diff.DiffContext;
import com.intellij.diff.fragments.LineFragment;
import com.intellij.diff.tools.fragmented.UnifiedDiffChange;
import com.intellij.diff.tools.fragmented.UnifiedDiffChangeUi;
import com.intellij.diff.tools.fragmented.UnifiedDiffViewer;
import com.intellij.diff.tools.fragmented.UnifiedFragmentBuilder;
import com.intellij.diff.util.DiffGutterRenderer;
import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.Side;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
@@ -47,6 +52,13 @@ public class UnifiedLocalChangeListDiffViewer extends UnifiedDiffViewer {
return group;
}
@NotNull
@Override
protected UnifiedDiffChangeUi createUi(@NotNull UnifiedDiffChange change) {
if (change instanceof MyUnifiedDiffChange) return new MyUnifiedDiffChangeUi(this, (MyUnifiedDiffChange)change);
return super.createUi(change);
}
@NotNull
private Runnable superComputeDifferences(@NotNull ProgressIndicator indicator) {
return super.computeDifferences(indicator);
@@ -185,6 +197,50 @@ public class UnifiedLocalChangeListDiffViewer extends UnifiedDiffViewer {
}
}
private static class MyUnifiedDiffChangeUi extends UnifiedDiffChangeUi {
private MyUnifiedDiffChangeUi(@NotNull UnifiedLocalChangeListDiffViewer viewer,
@NotNull MyUnifiedDiffChange change) {
super(viewer, change);
}
@NotNull
private UnifiedLocalChangeListDiffViewer getViewer() {
return (UnifiedLocalChangeListDiffViewer)myViewer;
}
@NotNull
private MyUnifiedDiffChange getChange() {
return ((MyUnifiedDiffChange)myChange);
}
@Override
protected void doInstallActionHighlighters() {
if (getViewer().myAllowExcludeChangesFromCommit && getChange().isFromActiveChangelist()) {
myOperations.add(new ExcludeGutterOperation());
}
super.doInstallActionHighlighters();
}
private class ExcludeGutterOperation extends MyGutterOperation {
@Override
public GutterIconRenderer createRenderer() {
if (!getChange().isFromActiveChangelist()) return null;
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 (!getViewer().isContentGood()) return;
int line = myViewer.transferLineFromOneside(Side.RIGHT, myChange.getLine1());
LocalTrackerDiffUtil.toggleRangeAtLine(getViewer().myTrackerActionProvider, line, isExcludedFromCommit);
}
};
}
}
}
private static class MyLocalTrackerActionProvider extends LocalTrackerDiffUtil.LocalTrackerActionProvider {
@NotNull private final UnifiedLocalChangeListDiffViewer myViewer;