diff: add "Show Diff in a New Tab|Window" action
authorDmitry Zhuravlev <dmitry.zhuravlev@jetbrains.com>
Fri, 9 Jul 2021 17:45:46 +0000 (17:45 +0000)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Fri, 9 Jul 2021 17:45:46 +0000 (17:45 +0000)
GitOrigin-RevId: 9d0c4e8c4fb6a875a94a342b50199feb2cb8f82a

13 files changed:
platform/diff-impl/src/com/intellij/diff/actions/ShowStandaloneDiffAction.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/actionSystem/ExtendableAction.java
platform/platform-resources-en/src/messages/ActionsBundle.properties
platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
platform/platform-resources/src/idea/PlatformActions.xml
platform/vcs-impl/resources/META-INF/VcsActions.xml
platform/vcs-impl/resources/META-INF/VcsExtensions.xml
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java
platform/vcs-log/impl/src/META-INF/vcs-log.xml
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/CompareRevisionsFromFileHistoryActionProvider.java
plugins/git4idea/resources/META-INF/plugin.xml
plugins/github/resources/META-INF/plugin.xml
plugins/svn4idea/src/META-INF/plugin.xml

diff --git a/platform/diff-impl/src/com/intellij/diff/actions/ShowStandaloneDiffAction.kt b/platform/diff-impl/src/com/intellij/diff/actions/ShowStandaloneDiffAction.kt
new file mode 100644 (file)
index 0000000..101b8fb
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. 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.actions
+
+import com.intellij.diff.editor.DiffEditorTabFilesManager.Companion.isDiffInEditor
+import com.intellij.idea.ActionsBundle.message
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.actionSystem.AnActionExtensionProvider
+import com.intellij.openapi.actionSystem.ExtendableAction
+import com.intellij.openapi.extensions.ExtensionPointName
+import com.intellij.openapi.project.DumbAware
+import com.intellij.openapi.util.registry.Registry
+
+/**
+ * In contrast to [ShowDiffAction] which may show diff preview, this action will show diff without selection tracking.
+ */
+class ShowStandaloneDiffAction : ExtendableAction(EP_NAME), DumbAware {
+  companion object {
+    @JvmStatic
+    val EP_NAME = ExtensionPointName.create<AnActionExtensionProvider>(
+      "com.intellij.diff.actions.ShowStandaloneDiffAction.ExtensionProvider")
+  }
+
+  override fun commonUpdate(e: AnActionEvent) {
+    val project = e.project
+
+    with(e.presentation) {
+      if (isDiffInEditor) {
+        text = message("action.Diff.ShowStandaloneDiff.tab.text")
+        description = message("action.Diff.ShowStandaloneDiff.tab.description")
+      }
+      else {
+        text = message("action.Diff.ShowStandaloneDiff.window.text")
+        description = message("action.Diff.ShowStandaloneDiff.window.description")
+      }
+
+      isEnabledAndVisible = project != null && Registry.`is`("show.editor.diff.preview", true)
+    }
+  }
+}
index 302a500287e5906c4527d546b66cf16c9c384775..68e505062ed1073ec0bae4c2d79dec0b4c86faa9 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.actionSystem;
 
 import com.intellij.openapi.extensions.ExtensionPointName;
@@ -30,6 +16,11 @@ public class ExtendableAction extends AnAction {
   public final void update(@NotNull AnActionEvent e) {
     e.getPresentation().copyFrom(getTemplatePresentation());
 
+    commonUpdate(e);
+    if (!e.getPresentation().isEnabled()) {
+      return;
+    }
+
     AnActionExtensionProvider provider = getProvider(e);
     if (provider != null) {
       provider.update(e);
@@ -55,6 +46,9 @@ public class ExtendableAction extends AnAction {
     return myExtensionPoint.findFirstSafe(provider -> provider.isActive(e));
   }
 
+  protected void commonUpdate(@NotNull AnActionEvent e) {
+  }
+
   protected void defaultUpdate(@NotNull AnActionEvent e) {
     e.getPresentation().setEnabledAndVisible(false);
   }
index be80cd7b7c2350c0ae52ce49224282f56712dcfd..6fa1b31837673563bcf4c1022c1ed7b06c7d0c71 100644 (file)
@@ -300,6 +300,12 @@ action.MemoryView.TrackingAction.NewInstancesTracking.text=Track New Instances
 action.Diff.ShowDiff.text=Show Diff
 action.Diff.ShowDiff.description=Compare files or revisions.
 action.Diff.ShowDiffPreview.description=Replace diff contents when selection changes
+action.Diff.ShowStandaloneDiff.text=Show Diff in a New Tab or Window
+action.Diff.ShowStandaloneDiff.description=Open diff for each selection in a new tab or window
+action.Diff.ShowStandaloneDiff.tab.text=Show Diff in a New Tab
+action.Diff.ShowStandaloneDiff.tab.description=Open diff for each selection in a new tab
+action.Diff.ShowStandaloneDiff.window.text=Show Diff in a New Window
+action.Diff.ShowStandaloneDiff.window.description=Open diff for each selection in a new window
 action.CompareTwoFiles.text=Compare _Files
 action.CompareTwoFiles.description=Compare two selected files or folders
 action.CompareFileWithEditor.text=Co_mpare File with Editor
index 5e7d8744e26b88e276a05fa19c6271e70b240c45..5937ca9ece56dc4f5c1e4194a7839093e034d9ff 100644 (file)
                     interface="com.intellij.openapi.actionSystem.AnActionExtensionProvider"
                     dynamic="true"/>
 
+    <extensionPoint name="diff.actions.ShowStandaloneDiffAction.ExtensionProvider"
+                    interface="com.intellij.openapi.actionSystem.AnActionExtensionProvider"
+                    dynamic="true"/>
+
     <extensionPoint name="jbProtocolCommand" interface="com.intellij.openapi.application.JBProtocolCommand" dynamic="true"/>
 
     <extensionPoint name="vfs.local.pluggableFileWatcher" interface="com.intellij.openapi.vfs.local.PluggableFileWatcher" />
index 7c1eac3f2244bdeae40b82be1146565418ff3290..a230ac351a580d44355f8670a4ae81ad1b994dc0 100644 (file)
     <group id="Diff.KeymapGroup" searchable="false">
       <action id="Diff.ShowDiff" class="com.intellij.diff.actions.ShowDiffAction"
               icon="AllIcons.Actions.Diff"/> <!-- CommonShortcuts.getDiff() -->
+      <action id="Diff.ShowStandaloneDiff" class="com.intellij.diff.actions.ShowStandaloneDiffAction" icon="AllIcons.Actions.Diff"/>
       <action id="CompareTwoFiles" class="com.intellij.diff.actions.CompareFilesAction" icon="AllIcons.Actions.Diff"/>
       <action id="CompareFileWithEditor" class="com.intellij.diff.actions.CompareFileWithEditorAction"/>
       <action id="CompareClipboardWithSelection" class="com.intellij.diff.actions.CompareClipboardWithSelectionAction"
index 03a25d6eb994bf23fbc64dfa7178a9366456250f..73685095818b8eaaac36850b86373be43ca41677 100644 (file)
       <reference ref="ChangesView.RevertFiles"/>
       <reference ref="ChangesView.Move"/>
       <reference ref="Diff.ShowDiff"/>
+      <reference ref="Diff.ShowStandaloneDiff"/>
       <reference ref="EditSource"/>
       <separator/>
       <reference ref="$Delete"/>
               icon="AllIcons.Vcs.Unshelve"/>
       <action id="ShelvedChanges.Restore" class="com.intellij.openapi.vcs.changes.shelf.RestoreShelvedChange"/>
       <reference id="Diff.ShowDiff"/>
+      <reference ref="Diff.ShowStandaloneDiff"/>
       <reference id="Vcs.ShowDiffWithLocal"/>
       <action id="ChangesView.CreatePatchFromChanges" class="com.intellij.openapi.vcs.changes.actions.CreatePatchFromChangesAction$Dialog"
               icon="AllIcons.Vcs.Patch"/>
index b08f7de9a8e91387baeb74236fc829d055c0a3c3..a0bdf6331eb808a04d03f3135ebe1d21e3173a57 100644 (file)
     <diff.impl.DiffToolSubstitutor implementation="com.intellij.openapi.vcs.changes.actions.diff.lst.LocalChangeListDiffTool$Unified"/>
 
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.shelf.DiffShelvedChangesActionProvider"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.shelf.DiffShelvedChangesActionProvider"/>
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.update.ShowUpdatedDiffActionProvider"/>
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.history.actions.CompareRevisionsAction"/>
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.actions.diff.ShowDiffFromLocalChangesActionProvider"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.actions.diff.ShowDiffFromLocalChangesActionProvider"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase$ShowStandaloneDiff"/>
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.ShowEditorDiffPreviewActionProvider" order="first"/>
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.openapi.vcs.changes.actions.diff.ShowDiffAction" order="last"/>
 
index 20dd48955e08150a2e5307da21a155751c81fa14..c86abd268e9813a66b2089438fa9cae068d68718 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 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.
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.vcs.changes.ui;
 
 import com.intellij.diff.DiffDialogHints;
@@ -27,6 +27,7 @@ import javax.swing.border.Border;
 import javax.swing.tree.DefaultTreeModel;
 import java.awt.*;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -175,7 +176,11 @@ public abstract class ChangesBrowserBase extends JPanel implements DataProvider
 
   @NotNull
   protected List<AnAction> createPopupMenuActions() {
-    return Collections.singletonList(myShowDiffAction);
+    List<AnAction> actions = new ArrayList<>();
+    actions.add(myShowDiffAction);
+    ContainerUtil.addIfNotNull(actions, ActionManager.getInstance().getAction("Diff.ShowStandaloneDiff"));
+
+    return actions;
   }
 
   @NotNull
@@ -267,11 +272,37 @@ public abstract class ChangesBrowserBase extends JPanel implements DataProvider
       previewManager.showDiffPreview(diffPreview);
     }
     else {
-      ListSelection<Object> selection = VcsTreeModelData.getListSelectionOrAll(myViewer);
-      ListSelection<ChangeDiffRequestChain.Producer> producers = selection.map(this::getDiffRequestProducer);
+      ShowStandaloneDiff.showStandaloneDiff(myProject, this);
+    }
+  }
+
+  public static class ShowStandaloneDiff implements AnActionExtensionProvider {
+
+    @Override
+    public boolean isActive(@NotNull AnActionEvent e) {
+      Project project = e.getProject();
+      ChangesBrowserBase changesBrowser = e.getData(DATA_KEY);
+      return project != null && changesBrowser != null;
+    }
+
+    @Override
+    public void update(@NotNull AnActionEvent e) {
+    }
+
+    @Override
+    public void actionPerformed(@NotNull AnActionEvent e) {
+      ChangesBrowserBase changesBrowser = e.getRequiredData(DATA_KEY);
+      Project project = e.getRequiredData(CommonDataKeys.PROJECT);
+
+      showStandaloneDiff(project, changesBrowser);
+    }
+
+    public static void showStandaloneDiff(@NotNull Project project, @NotNull ChangesBrowserBase changesBrowser) {
+      ListSelection<Object> selection = VcsTreeModelData.getListSelectionOrAll(changesBrowser.myViewer);
+      ListSelection<ChangeDiffRequestChain.Producer> producers = selection.map(changesBrowser::getDiffRequestProducer);
       DiffRequestChain chain = new ChangeDiffRequestChain(producers.getList(), producers.getSelectedIndex());
-      updateDiffContext(chain);
-      DiffManager.getInstance().showDiff(myProject, chain, new DiffDialogHints(null, this));
+      changesBrowser.updateDiffContext(chain);
+      DiffManager.getInstance().showDiff(project, chain, new DiffDialogHints(null, changesBrowser));
     }
   }
 
@@ -295,7 +326,6 @@ public abstract class ChangesBrowserBase extends JPanel implements DataProvider
     }
   }
 
-
   protected static class ChangesBrowserTreeList extends ChangesTree {
     @NotNull private final ChangesBrowserBase myViewer;
 
index 446108773eee4d18ab75bac564e0e921c371a0fe..c8f003624b555ba32c82d46ab8938e446f6e4c73 100644 (file)
@@ -55,7 +55,9 @@
     <getDataRule key="Vcs.Log.UiEx" implementationClass="com.intellij.vcs.log.ui.VcsLogUiExDataRule"/>
 
     <diff.actions.ShowDiffAction.ExtensionProvider
-        implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromFileHistoryActionProvider"/>
+        implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromFileHistoryActionProvider$ShowDiff"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider
+        implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromFileHistoryActionProvider$ShowStandaloneDiff"/>
     <openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider
         implementation="com.intellij.vcs.log.ui.actions.history.ShowDiffAfterWithLocalFromFileHistoryActionProvider"/>
     <openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider
       <reference id="Vcs.Log.OpenRepositoryVersion"/>
       <reference id="Vcs.ShowDiffWithLocal"/>
       <reference id="Diff.ShowDiff"/>
+      <reference ref="Diff.ShowStandaloneDiff"/>
       <reference id="Vcs.Log.ShowAllAffected"/>
       <reference id="Vcs.Log.AnnotateRevisionAction"/>
       <reference id="VcsHistoryActionsGroup"/>
index 5b0af283d12d9deb7a5c88971ccadb2f7aa1f6b2..f2e30120e586bfba2bd738adc69fd92dc6f9b794 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.vcs.log.ui.actions.history;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull;
 import java.awt.event.KeyEvent;
 import java.util.Arrays;
 
-public class CompareRevisionsFromFileHistoryActionProvider implements AnActionExtensionProvider {
+abstract public class CompareRevisionsFromFileHistoryActionProvider implements AnActionExtensionProvider {
   @Override
   public boolean isActive(@NotNull AnActionEvent e) {
     FilePath filePath = e.getData(VcsDataKeys.FILE_PATH);
@@ -36,7 +36,7 @@ public class CompareRevisionsFromFileHistoryActionProvider implements AnActionEx
       return;
     }
 
-    setTextAndDescription(e, log);
+    updateActionText(e, log);
     e.getPresentation().setVisible(true);
 
     if (e.getInputEvent() instanceof KeyEvent) {
@@ -48,6 +48,8 @@ public class CompareRevisionsFromFileHistoryActionProvider implements AnActionEx
     }
   }
 
+  protected void updateActionText(@NotNull AnActionEvent e, @NotNull VcsLog log) {}
+
   @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
     VcsLogUsageTriggerCollector.triggerUsage(e, this);
@@ -69,4 +71,13 @@ public class CompareRevisionsFromFileHistoryActionProvider implements AnActionEx
       e.getPresentation().setDescription(VcsLogBundle.messagePointer("action.presentation.CompareRevisionsFromFileHistoryActionProvider.description.show.diff"));
     }
   }
+
+  static class ShowDiff extends CompareRevisionsFromFileHistoryActionProvider {
+    @Override
+    protected void updateActionText(@NotNull AnActionEvent e, @NotNull VcsLog log) {
+      setTextAndDescription(e, log);
+    }
+  }
+
+  static class ShowStandaloneDiff extends CompareRevisionsFromFileHistoryActionProvider {}
 }
index 40a342fb53a577eb63bbf873ebbbb9399e76f4fb..32ec46f77ec562a55ee237039ff526e9df3d6e7a 100644 (file)
       <reference id="Git.Ignore.File"/>
       <separator/>
       <reference id="Diff.ShowDiff"/>
+      <reference ref="Diff.ShowStandaloneDiff"/>
       <reference id="Git.Stage.ThreeSideDiff"/>
       <reference ref="EditSource"/>
       <reference ref="ChangesView.CreatePatchFromChanges"/>
       <reference id="Git.Stash.Drop"/>
       <separator/>
       <reference id="Diff.ShowDiff"/>
+      <reference ref="Diff.ShowStandaloneDiff"/>
       <reference id="Vcs.ShowDiffWithLocal"/>
       <reference id="Vcs.ShowDiffWithLocal.Before"/>
     </group>
     <vcs.fileStatusProvider implementation="git4idea.index.vfs.GitIndexVirtualFileStatusProvider"/>
 
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="git4idea.index.actions.GitStageDiffAction"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider implementation="git4idea.index.actions.GitStageDiffAction"/>
     <openapi.vcs.changes.actions.CreatePatchFromChangesAction.Dialog.ExtensionProvider
       implementation="git4idea.index.actions.GitStageCreatePatchActionProvider$Dialog"/>
     <openapi.vcs.changes.actions.CreatePatchFromChangesAction.Clipboard.ExtensionProvider
     <projectService serviceImplementation="git4idea.stash.GitStashCache"/>
     <postStartupActivity implementation="git4idea.stash.ui.GitStashStartupActivity"/>
     <diff.actions.ShowDiffAction.ExtensionProvider implementation="git4idea.stash.ui.GitShowDiffFromStashAction"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider implementation="git4idea.stash.ui.GitShowDiffFromStashAction"/>
 
     <vcs.consoleFolding implementation="git4idea.console.GitConsoleFolding"/>
     <console.folding implementation="git4idea.console.GitProgressOutputConsoleFolding"/>
index b803bcdc0aebc1458c1c8042360ae8590dd21b9b..d0746de5185b87ca9923368a5c970952bf6540ba 100644 (file)
@@ -68,6 +68,8 @@
 
     <diff.actions.ShowDiffAction.ExtensionProvider
       implementation="org.jetbrains.plugins.github.pullrequest.action.GHPRShowDiffActionProvider"/>
+    <diff.actions.ShowStandaloneDiffAction.ExtensionProvider
+      implementation="org.jetbrains.plugins.github.pullrequest.action.GHPRShowDiffActionProvider"/>
 
     <fileIconProvider implementation="org.jetbrains.plugins.github.extensions.GithubYamlIconProvider"/>
   </extensions>
 
     <group id="Github.PullRequest.Changes.Popup">
       <reference id="Diff.ShowDiff"/>
+      <reference id="Diff.ShowStandaloneDiff"/>
       <reference id="Github.PullRequest.Changes.Reload"/>
     </group>
 
       <add-to-group group-id="Diff.EditorPopupMenu"/>
     </action>
   </actions>
-</idea-plugin>
\ No newline at end of file
+</idea-plugin>
index cd2f6a4415508251321510763c42df8d329fff2d..f0733feb94b1787ba3301f964cf918b1d0a1ae81 100644 (file)
@@ -82,7 +82,7 @@
       <add-to-group group-id="SubversionFilePopupGroup" anchor="last"/>
     </group>
     <reference id="Subversion.MarkTreeResolved">
-      <add-to-group group-id="ChangesViewPopupMenu" anchor="after" relative-to-action="Diff.ShowDiff"/>
+      <add-to-group group-id="ChangesViewPopupMenu" anchor="after" relative-to-action="Diff.ShowStandaloneDiff"/>
     </reference>
     <group id="SubversionUpdateActionGroup" class="org.jetbrains.idea.svn.actions.SubversionGroup">
       <reference ref="ChangesView.AddUnversioned"/>