IDEA-267354 git: show 'Merge' action on hover in Local Changes
[idea/community.git] / plugins / git4idea / src / git4idea / merge / GitChangesViewNodeAction.kt
1 // 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.
2 package git4idea.merge
3
4 import com.intellij.icons.AllIcons
5 import com.intellij.openapi.project.Project
6 import com.intellij.openapi.vcs.FileStatus
7 import com.intellij.openapi.vcs.changes.Change
8 import com.intellij.openapi.vcs.changes.ChangesUtil
9 import com.intellij.openapi.vcs.changes.ChangesViewNodeAction
10 import com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode
11 import com.intellij.openapi.vcs.changes.ui.HoverIcon
12 import git4idea.conflicts.showMergeWindow
13 import git4idea.i18n.GitBundle
14 import git4idea.index.ui.createMergeHandler
15 import git4idea.index.ui.isReversedRoot
16 import git4idea.repo.GitRepositoryManager
17
18 class GitChangesViewNodeAction(val project: Project) : ChangesViewNodeAction {
19   override fun createNodeHoverIcon(node: ChangesBrowserNode<*>): HoverIcon? {
20     val change = node.userObject as? Change ?: return null
21     if (change.fileStatus != FileStatus.MERGED_WITH_CONFLICTS) return null
22
23     val path = ChangesUtil.getFilePath(change)
24     val stagingAreaHolder = GitRepositoryManager.getInstance(project).getRepositoryForFileQuick(path)?.stagingAreaHolder
25     if (stagingAreaHolder?.findConflict(path) == null) return null
26
27     return GitMergeHoverIcon(project)
28   }
29
30   private data class GitMergeHoverIcon(val project: Project)
31     : HoverIcon(AllIcons.Vcs.Merge, GitBundle.message("changes.view.merge.action.text")) {
32     override fun invokeAction(node: ChangesBrowserNode<*>) {
33       val change = node.userObject as? Change ?: return
34
35       val path = ChangesUtil.getFilePath(change)
36       val stagingAreaHolder = GitRepositoryManager.getInstance(project).getRepositoryForFileQuick(path)?.stagingAreaHolder
37       val conflict = stagingAreaHolder?.findConflict(path) ?: return
38
39       showMergeWindow(project, createMergeHandler(project), listOf(conflict), project::isReversedRoot)
40     }
41   }
42 }