From abdcf1913da9c1d5812f2e102b52596cf8ddf7b2 Mon Sep 17 00:00:00 2001 From: "Ilia.Shulgin" Date: Fri, 3 Oct 2025 13:22:10 +0200 Subject: [PATCH] [vcs] IJPL-173924 Inline ChangesTreeEditorDiffPreview GitOrigin-RevId: 494970d849802143ee665cbb8499fe906c080566 --- platform/vcs-impl/api-dump.txt | 30 +++--- .../changes/ChangesTreeEditorDiffPreview.kt | 93 ------------------- .../ui/TreeHandlerDiffRequestProcessor.kt | 85 ++++++++++++++++- 3 files changed, 95 insertions(+), 113 deletions(-) delete mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesTreeEditorDiffPreview.kt diff --git a/platform/vcs-impl/api-dump.txt b/platform/vcs-impl/api-dump.txt index 98ecf2e9b29d..825d07ffd87d 100644 --- a/platform/vcs-impl/api-dump.txt +++ b/platform/vcs-impl/api-dump.txt @@ -755,22 +755,6 @@ a:com.intellij.openapi.vcs.changes.ChangeViewDiffRequestProcessor$Wrapper f:com.intellij.openapi.vcs.changes.ChangesPreprocess - ():V - s:preprocessChangesRemoveDeletedForDuplicateMoved(java.util.List):java.util.List -a:com.intellij.openapi.vcs.changes.ChangesTreeEditorDiffPreview -- com.intellij.openapi.vcs.changes.EditorTabDiffPreview -- (com.intellij.openapi.vcs.changes.ui.ChangesTree,javax.swing.JComponent):V -- b:(com.intellij.openapi.vcs.changes.ui.ChangesTree,javax.swing.JComponent,I,kotlin.jvm.internal.DefaultConstructorMarker):V -- pf:getTree():com.intellij.openapi.vcs.changes.ui.ChangesTree -- handleDoubleClick(java.awt.event.MouseEvent):Z -- handleEnterKey():Z -- p:handleEscapeKey():V -- p:handleNextDiffShortcut():V -- p:handleSingleClick():V -- p:isOpenPreviewWithNextDiffShortcut():Z -- p:isOpenPreviewWithSingleClick():Z -- p:isOpenPreviewWithSingleClickEnabled():Z -- p:isPreviewOnDoubleClick():Z -- p:isPreviewOnEnter():Z -- p:returnFocusToTree():V com.intellij.openapi.vcs.changes.ChangesViewEx - com.intellij.openapi.vcs.changes.ChangesViewI - a:getCommitWorkflowHandler():com.intellij.vcs.commit.ChangesViewCommitWorkflowHandler @@ -2623,7 +2607,7 @@ c:com.intellij.openapi.vcs.changes.ui.TreeHandlerDiffRequestProcessor - pf:selectChange(com.intellij.openapi.vcs.changes.ChangeViewDiffRequestProcessor$Wrapper):V - p:showAllChangesForEmptySelection():Z a:com.intellij.openapi.vcs.changes.ui.TreeHandlerEditorDiffPreview -- com.intellij.openapi.vcs.changes.ChangesTreeEditorDiffPreview +- com.intellij.openapi.vcs.changes.EditorTabDiffPreview - sf:Companion:com.intellij.openapi.vcs.changes.ui.TreeHandlerEditorDiffPreview$Companion - (com.intellij.openapi.vcs.changes.ui.ChangesTree,com.intellij.openapi.vcs.changes.ui.ChangesTreeDiffPreviewHandler):V - (com.intellij.openapi.vcs.changes.ui.ChangesTree,javax.swing.JComponent,com.intellij.openapi.vcs.changes.ui.ChangesTreeDiffPreviewHandler):V @@ -2634,7 +2618,19 @@ a:com.intellij.openapi.vcs.changes.ui.TreeHandlerEditorDiffPreview - pf:getEditorTabName(com.intellij.diff.impl.DiffEditorViewer):java.lang.String - a:getEditorTabName(com.intellij.openapi.vcs.changes.ChangeViewDiffRequestProcessor$Wrapper):java.lang.String - pf:getHandler():com.intellij.openapi.vcs.changes.ui.ChangesTreeDiffPreviewHandler +- pf:getTree():com.intellij.openapi.vcs.changes.ui.ChangesTree +- handleDoubleClick(java.awt.event.MouseEvent):Z +- handleEnterKey():Z +- p:handleEscapeKey():V +- p:handleNextDiffShortcut():V +- p:handleSingleClick():V - f:hasContent():Z +- p:isOpenPreviewWithNextDiffShortcut():Z +- p:isOpenPreviewWithSingleClick():Z +- p:isOpenPreviewWithSingleClickEnabled():Z +- p:isPreviewOnDoubleClick():Z +- p:isPreviewOnEnter():Z +- p:returnFocusToTree():V f:com.intellij.openapi.vcs.changes.ui.TreeHandlerEditorDiffPreview$Companion - f:createDefaultViewer(com.intellij.openapi.vcs.changes.ui.ChangesTree,com.intellij.openapi.vcs.changes.ui.ChangesTreeDiffPreviewHandler,java.lang.String):com.intellij.diff.impl.DiffEditorViewer a:com.intellij.openapi.vcs.changes.ui.VcsToolWindowFactory diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesTreeEditorDiffPreview.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesTreeEditorDiffPreview.kt deleted file mode 100644 index 7ebc64eb9df3..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesTreeEditorDiffPreview.kt +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.openapi.vcs.changes - -import com.intellij.openapi.actionSystem.ActionManager -import com.intellij.openapi.actionSystem.ActionUpdateThread -import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.actionSystem.IdeActions -import com.intellij.openapi.application.ApplicationManager.getApplication -import com.intellij.openapi.project.DumbAwareAction -import com.intellij.openapi.vcs.VcsConfiguration -import com.intellij.openapi.vcs.changes.ui.ChangesTree -import com.intellij.ui.ExpandableItemsHandler -import com.intellij.util.EditSourceOnDoubleClickHandler -import com.intellij.util.Processor -import com.intellij.util.ui.UIUtil -import java.awt.event.MouseEvent -import javax.swing.JComponent - -abstract class ChangesTreeEditorDiffPreview( - protected val tree: ChangesTree, - targetComponent: JComponent = tree, -) : EditorTabDiffPreview(tree.project) { - - init { - tree.doubleClickHandler = Processor { e -> handleDoubleClick(e) } - tree.enterKeyHandler = Processor { e -> handleEnterKey() } - tree.addSelectionListener { handleSingleClick() } - PreviewOnNextDiffAction().registerCustomShortcutSet(targetComponent, this) - - UIUtil.putClientProperty(tree, ExpandableItemsHandler.IGNORE_ITEM_SELECTION, true) - } - - protected open fun isPreviewOnDoubleClick(): Boolean = true - open fun handleDoubleClick(e: MouseEvent): Boolean { - if (!isPreviewOnDoubleClick()) return false - if (EditSourceOnDoubleClickHandler.isToggleEvent(tree, e)) return false - return performDiffAction() - } - - protected open fun isPreviewOnEnter(): Boolean = true - open fun handleEnterKey(): Boolean { - if (!isPreviewOnEnter()) return false - return performDiffAction() - } - - protected open fun isOpenPreviewWithSingleClickEnabled(): Boolean = false - protected open fun isOpenPreviewWithSingleClick(): Boolean { - if (!isOpenPreviewWithSingleClickEnabled()) return false - if (!VcsConfiguration.getInstance(project).LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN) return false - return true - } - - protected open fun handleSingleClick() { - if (!isOpenPreviewWithSingleClick()) return - val opened = openPreview(false) - if (!opened) { - closePreview() // auto-close editor tab if nothing to preview - } - } - - protected open fun isOpenPreviewWithNextDiffShortcut(): Boolean = true - protected open fun handleNextDiffShortcut() { - if (!isOpenPreviewWithNextDiffShortcut()) return - openPreview(true) - } - - override fun handleEscapeKey() { - closePreview() - // closing the diff preview editor schedules focus switch to "some" other editor in JBTabsImpl - // we can't disable that, so we have to manually override the focus - getApplication().invokeLater { - returnFocusToTree() - } - } - - protected open fun returnFocusToTree() = Unit - - private inner class PreviewOnNextDiffAction : DumbAwareAction() { - init { - copyShortcutFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_DIFF)) - } - - override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT - - override fun update(e: AnActionEvent) { - e.presentation.isEnabledAndVisible = isOpenPreviewWithNextDiffShortcut() - } - - override fun actionPerformed(e: AnActionEvent) { - handleNextDiffShortcut() - } - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeHandlerDiffRequestProcessor.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeHandlerDiffRequestProcessor.kt index 79452a6da280..2a650762398c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeHandlerDiffRequestProcessor.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeHandlerDiffRequestProcessor.kt @@ -7,13 +7,23 @@ import com.intellij.diff.impl.DiffEditorViewer import com.intellij.diff.tools.combined.* import com.intellij.diff.util.DiffUtil import com.intellij.openapi.ListSelection +import com.intellij.openapi.actionSystem.ActionManager +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.IdeActions +import com.intellij.openapi.application.ApplicationManager.getApplication +import com.intellij.openapi.project.DumbAwareAction import com.intellij.openapi.util.Disposer +import com.intellij.openapi.vcs.VcsConfiguration import com.intellij.openapi.vcs.changes.Change import com.intellij.openapi.vcs.changes.ChangeViewDiffRequestProcessor import com.intellij.openapi.vcs.changes.ChangeViewDiffRequestProcessor.Wrapper -import com.intellij.openapi.vcs.changes.ChangesTreeEditorDiffPreview +import com.intellij.openapi.vcs.changes.EditorTabDiffPreview import com.intellij.openapi.vcs.changes.actions.diff.WrapperCombinedBlockProducer import com.intellij.openapi.vcs.changes.actions.diff.prepareCombinedBlocksFromWrappers +import com.intellij.ui.ExpandableItemsHandler +import com.intellij.util.EditSourceOnDoubleClickHandler +import com.intellij.util.Processor import com.intellij.util.containers.JBIterable import com.intellij.util.ui.UIUtil import com.intellij.util.ui.tree.TreeUtil @@ -24,6 +34,7 @@ import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.CalledInAny import java.awt.event.FocusAdapter import java.awt.event.FocusEvent +import java.awt.event.MouseEvent import java.beans.PropertyChangeListener import javax.swing.JComponent import javax.swing.JTree @@ -191,12 +202,64 @@ open class TreeHandlerChangesTreeTracker( abstract class TreeHandlerEditorDiffPreview( - tree: ChangesTree, + protected val tree: ChangesTree, targetComponent: JComponent = tree, protected val handler: ChangesTreeDiffPreviewHandler -) : ChangesTreeEditorDiffPreview(tree, targetComponent) { +) : EditorTabDiffPreview(tree.project) { constructor(tree: ChangesTree, handler: ChangesTreeDiffPreviewHandler) : this(tree, tree, handler) + init { + tree.doubleClickHandler = Processor { e -> handleDoubleClick(e) } + tree.enterKeyHandler = Processor { _ -> handleEnterKey() } + tree.addSelectionListener { handleSingleClick() } + PreviewOnNextDiffAction().registerCustomShortcutSet(targetComponent, this) + + UIUtil.putClientProperty(tree, ExpandableItemsHandler.IGNORE_ITEM_SELECTION, true) + } + + protected open fun isPreviewOnDoubleClick(): Boolean = true + open fun handleDoubleClick(e: MouseEvent): Boolean { + if (!isPreviewOnDoubleClick()) return false + if (EditSourceOnDoubleClickHandler.isToggleEvent(tree, e)) return false + return performDiffAction() + } + + protected open fun isPreviewOnEnter(): Boolean = true + open fun handleEnterKey(): Boolean { + if (!isPreviewOnEnter()) return false + return performDiffAction() + } + + protected open fun isOpenPreviewWithSingleClickEnabled(): Boolean = false + protected open fun isOpenPreviewWithSingleClick(): Boolean { + if (!isOpenPreviewWithSingleClickEnabled()) return false + if (!VcsConfiguration.getInstance(project).LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN) return false + return true + } + + protected open fun handleSingleClick() { + if (!isOpenPreviewWithSingleClick()) return + val opened = openPreview(false) + if (!opened) { + closePreview() // auto-close editor tab if nothing to preview + } + } + + protected open fun isOpenPreviewWithNextDiffShortcut(): Boolean = true + protected open fun handleNextDiffShortcut() { + if (!isOpenPreviewWithNextDiffShortcut()) return + openPreview(true) + } + + override fun handleEscapeKey() { + closePreview() + getApplication().invokeLater { + returnFocusToTree() + } + } + + protected open fun returnFocusToTree() = Unit + final override fun hasContent(): Boolean { return handler.hasContent(tree) } @@ -223,6 +286,22 @@ abstract class TreeHandlerEditorDiffPreview( @CalledInAny abstract fun getEditorTabName(wrapper: Wrapper?): String? + private inner class PreviewOnNextDiffAction : DumbAwareAction() { + init { + copyShortcutFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_DIFF)) + } + + override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT + + override fun update(e: AnActionEvent) { + e.presentation.isEnabledAndVisible = isOpenPreviewWithNextDiffShortcut() + } + + override fun actionPerformed(e: AnActionEvent) { + handleNextDiffShortcut() + } + } + companion object { fun createDefaultViewer(changesTree: ChangesTree, previewHandler: ChangesTreeDiffPreviewHandler, place: String): DiffEditorViewer { val processor = if (CombinedDiffRegistry.isEnabled()) {