mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
git-index: support navigation between files in diff
GitOrigin-RevId: 49bb4d7607a7b812387ee736232cc59cf1b826cc
This commit is contained in:
committed by
intellij-monorepo-bot
parent
70bef3e687
commit
709cabb3b5
@@ -11,31 +11,35 @@ import com.intellij.util.containers.isEmpty
|
||||
import git4idea.index.createThreeSidesDiffRequestProducer
|
||||
import git4idea.index.createTwoSidesDiffRequestProducer
|
||||
import git4idea.index.ui.GIT_FILE_STATUS_NODES_STREAM
|
||||
import git4idea.index.ui.GIT_STAGE_TRACKER
|
||||
import kotlin.streams.toList
|
||||
import git4idea.index.ui.GIT_STAGE_TREE
|
||||
|
||||
class GitStageDiffAction : AnActionExtensionProvider {
|
||||
override fun isActive(e: AnActionEvent): Boolean = e.getData(GIT_STAGE_TRACKER) != null
|
||||
override fun isActive(e: AnActionEvent): Boolean = e.getData(GIT_STAGE_TREE) != null
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = e.project != null && !e.getData(GIT_FILE_STATUS_NODES_STREAM).isEmpty()
|
||||
e.presentation.isEnabled = e.project != null &&
|
||||
!e.getData(GIT_FILE_STATUS_NODES_STREAM).isEmpty()
|
||||
e.presentation.isVisible = e.presentation.isEnabled || e.isFromActionToolbar
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val producers = e.getRequiredData(GIT_FILE_STATUS_NODES_STREAM).map { createTwoSidesDiffRequestProducer(e.project!!, it) }.toList()
|
||||
DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers, 0), DiffDialogHints.DEFAULT)
|
||||
val producers = e.getRequiredData(GIT_STAGE_TREE).statusNodesListSelection(true)
|
||||
.map { createTwoSidesDiffRequestProducer(e.project!!, it) }
|
||||
DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers.list, producers.selectedIndex), DiffDialogHints.DEFAULT)
|
||||
}
|
||||
}
|
||||
|
||||
class GitStageThreeSideDiffAction : DumbAwareAction() {
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = e.project != null && !e.getData(GIT_FILE_STATUS_NODES_STREAM).isEmpty()
|
||||
e.presentation.isEnabled = e.project != null &&
|
||||
e.getData(GIT_STAGE_TREE) != null &&
|
||||
!e.getData(GIT_FILE_STATUS_NODES_STREAM).isEmpty()
|
||||
e.presentation.isVisible = e.presentation.isEnabled || e.isFromActionToolbar
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val producers = e.getRequiredData(GIT_FILE_STATUS_NODES_STREAM).map { createThreeSidesDiffRequestProducer(e.project!!, it) }.toList()
|
||||
DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers, 0), DiffDialogHints.DEFAULT)
|
||||
val producers = e.getRequiredData(GIT_STAGE_TREE).statusNodesListSelection(false)
|
||||
.map { createThreeSidesDiffRequestProducer(e.project!!, it) }
|
||||
DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers.list, producers.selectedIndex), DiffDialogHints.DEFAULT)
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.intellij.ide.dnd.DnDDragStartBean
|
||||
import com.intellij.ide.dnd.DnDEvent
|
||||
import com.intellij.ide.util.treeView.TreeState
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.ListSelection
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.DataKey
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||
@@ -27,6 +28,7 @@ import com.intellij.ui.ClickListener
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import com.intellij.util.FontUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.isEmpty
|
||||
import git4idea.conflicts.getConflictType
|
||||
import git4idea.i18n.GitBundle
|
||||
@@ -50,6 +52,7 @@ import javax.swing.tree.TreePath
|
||||
import kotlin.streams.toList
|
||||
|
||||
val GIT_FILE_STATUS_NODES_STREAM = DataKey.create<Stream<GitFileStatusNode>>("GitFileStatusNodesStream")
|
||||
val GIT_STAGE_TREE = DataKey.create<GitStageTree>("GitStageTree")
|
||||
|
||||
abstract class GitStageTree(project: Project, parentDisposable: Disposable) : ChangesTree(project, false, true) {
|
||||
private var hoverNode: ChangesBrowserNode<*>? = null
|
||||
@@ -113,6 +116,7 @@ abstract class GitStageTree(project: Project, parentDisposable: Disposable) : Ch
|
||||
|
||||
override fun getData(dataId: String): Any? {
|
||||
return when {
|
||||
GIT_STAGE_TREE.`is`(dataId) -> this
|
||||
GIT_FILE_STATUS_NODES_STREAM.`is`(dataId) -> selectedStatusNodes()
|
||||
VcsDataKeys.FILE_PATH_STREAM.`is`(dataId) -> selectedStatusNodes().map { it.filePath }
|
||||
VcsDataKeys.VIRTUAL_FILE_STREAM.`is`(dataId) -> selectedStatusNodes().map { it.filePath.virtualFile }.filter { it != null }
|
||||
@@ -126,11 +130,40 @@ abstract class GitStageTree(project: Project, parentDisposable: Disposable) : Ch
|
||||
}
|
||||
|
||||
fun selectedStatusNodes(): Stream<GitFileStatusNode> {
|
||||
return VcsTreeModelData.selected(this).userObjectsStream()
|
||||
.filter { it is GitFileStatusNode }
|
||||
.map { it as GitFileStatusNode }
|
||||
return VcsTreeModelData.selected(this).userObjectsStream(GitFileStatusNode::class.java)
|
||||
}
|
||||
|
||||
fun statusNodesListSelection(preferLimitedContext: Boolean): ListSelection<GitFileStatusNode> {
|
||||
val entries = VcsTreeModelData.selected(this).userObjects(GitFileStatusNode::class.java)
|
||||
if (entries.size > 1) {
|
||||
return ListSelection.createAt(entries, 0)
|
||||
}
|
||||
|
||||
val selected = entries.singleOrNull()
|
||||
val selectedKind = selected?.kind
|
||||
|
||||
val allEntriesData: VcsTreeModelData = when {
|
||||
preferLimitedContext && (selectedKind == NodeKind.UNSTAGED || selectedKind == NodeKind.UNTRACKED) -> {
|
||||
VcsTreeModelData.allUnderTag(this, NodeKind.UNSTAGED)
|
||||
}
|
||||
preferLimitedContext && selectedKind == NodeKind.STAGED -> {
|
||||
VcsTreeModelData.allUnderTag(this, NodeKind.STAGED)
|
||||
}
|
||||
else -> {
|
||||
VcsTreeModelData.all(this)
|
||||
}
|
||||
}
|
||||
|
||||
val allEntries = allEntriesData.userObjects(GitFileStatusNode::class.java)
|
||||
return if (allEntries.size <= entries.size) {
|
||||
ListSelection.createAt(entries, 0)
|
||||
}
|
||||
else {
|
||||
ListSelection.create(allEntries, selected)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private inner class MyTreeModelBuilder internal constructor(project: Project, grouping: ChangesGroupingPolicyFactory)
|
||||
: TreeModelBuilder(project, grouping) {
|
||||
private val parentNodes: MutableMap<NodeKind, ChangesBrowserKindNode> = mutableMapOf()
|
||||
|
||||
Reference in New Issue
Block a user