diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffChangeUi.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffChangeUi.java index 097355d8f359..dec5d83f03e3 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffChangeUi.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffChangeUi.java @@ -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 myHighlighters = new ArrayList<>(); - @NotNull private final List myOperations = new ArrayList<>(); + @NotNull protected final List myHighlighters = new ArrayList<>(); + @NotNull protected final List 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, diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/LocalTrackerDiffUtil.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/LocalTrackerDiffUtil.kt index 1254ff26cff3..968f7d80acda 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/LocalTrackerDiffUtil.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/LocalTrackerDiffUtil.kt @@ -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 { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/SimpleLocalChangeListDiffViewer.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/SimpleLocalChangeListDiffViewer.java index cefb8a6dfa03..5e704828fe4f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/SimpleLocalChangeListDiffViewer.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/SimpleLocalChangeListDiffViewer.java @@ -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); } }; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/UnifiedLocalChangeListDiffViewer.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/UnifiedLocalChangeListDiffViewer.java index 2ca32a12716a..cb6c8b0fa3b3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/UnifiedLocalChangeListDiffViewer.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/lst/UnifiedLocalChangeListDiffViewer.java @@ -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;